美文网首页
排序算法(java实现)

排序算法(java实现)

作者: 未闻花名未见你 | 来源:发表于2019-04-26 17:32 被阅读0次

本文均为升序算法

简单选择排序

  1. 将序列最小(or最大)值元素放在待排序序列首位,
  2. 从剩余待排序序列中选最小(or最大)元素,放在待排序序列首位(也就是总序列的第二个位置),
  3. 以此类推。。。
public static void simpleSelectSort(int[] array) {
    int len = array.length;
    int temp = 0;
    for (int i = 0; i < len; i++) {
        for (int j = i + 1; j < len; j++) {
            //始终用待排序列的首位元素与后面的元素比较
            if (array[i] > array[j]) {
                //交换元素
               temp = array[i];
               array[i] = array[j];
               array[j] = temp;
            }
        }
    }
}

改进选择排序1

上述排序内循环每次都交换元素,可以改进为,只记录元素位置,内循环完成后只交换一次元素即可

public static  void selectSort1(int[] array) {
    int len = array.length;
    int temp = 0;
    int minIndex = 0;
    for (int i = 0; i < len; i++) {
        minIndex = i;
        for (int j = i + 1; j < len; j++) {
            if (array[i] > array[j]) {
                minIndex = j;
            }
        }
        if (minIndex > i) {
            temp = array[i];
            array[i] = array[minIndex];
            array[minIndex] = temp;
        }
    }

改进的选择排序2

内循环从待排序数组两端开始比较,一次循环后最小、最大值分别排在两端

public static void selectSort2(int[] array) {
    int len = array.length;
    for (int i = 0; i < len/2 + 1; i++) {
        int minIndex = i;
        int maxIndex = i;
        int minVal = array[minIndex];
        int maxVal = array[maxIndex];
        for (int j = i + 1; j < len - i; j++) {
            //每一次比较,都更新最值的index,value
            if (array[j] > maxVal) {
                maxIndex = j;
                maxVal = array[j];
            }
            if (array[j] < minVal) {
                minIndex = j;
                minVal = array[j];
            }
        }
        int temp = 0;
        if (minIndex > i) {
            temp = array[minIndex];
            array[minIndex] = array[i];
            array[i] = temp;
        }
        if (maxIndex < len - 1 - i) {
            temp = array[maxIndex];
            array[maxIndex] = array[len - 1 - i];
            array[len - 1 - i] = temp;
        }
        print(array);
    }
}

冒泡排序

  1. 从序列起始位置,两两比较,符合条件就交换位置,将最大值(or最小)确定在序列末尾
  2. 重复1的逻辑,将最值确定在序列倒数第二位
  3. 以此类推
public static void bubbleSort(int[] array) {
    int len = array.length;
    for (int i = 0; i < len; i++) {
        int temp = 0;
        for (int j = 0; j < len - 1- i; j++) {
            if (array[j] > array[j + 1]) {
                temp = array[j];
                array[j] = array[j + 1];
                array[j + 1] = temp;
            }
        }
    }
}

改进的冒泡排序1

增加有序标志,比如1,2,3,4,9,6,前四个元素有序,当待排序列为1,2,3,4就可以结束了
因此增加一个数据交换标识,有数据交换表示无序,无数据交换就结束比较,选择用while控制外层循环

public static void bubbleSort1(int[] array) {
    int len = array.length;
    int temp = 0;
    boolean flag = true;//数据交换标识,默认为有,表明待排序列无序
    while(flag) {
        flag = false;
        for (int j = 0; j < len - 1; j++) {
            if (array[j] > array[j + 1]) {
                temp = array[j];
                array[j] = array[j + 1];
                array[j + 1] = temp;
                flag = true;
            }
        }
        len--;
    }
}

冒泡排序改进2

5,3,2,8,9,10,后三个元素不用排序,因此算法中对后三个元素的比较是多余的,可以简化,记录内循环最后一次元素交换的位置,下一轮循环,以该位置作为元素比较的边界(注意是比较)

public static void bubbleSort2(int[] array) {
    int len = array.length;
    int flag = len;//设置待排序序列的边界,默认为整个序列
    int temp = 0;
    while (flag>0) {//如果flag=0,表示上一次循环没有元素交换,序列已经有序
        flag = 0;
        for (int i = 1; i < len; i++) {
            if (array[i - 1] > array[i]) { //交换数据
                temp = array[i];
                array[i] = array[i-1];
                array[i-1] = temp;
                flag = i; //记录最新边界
            }
        }
        len = flag;//该边界作为下一次循环的限制条件
    }
}

插入排序

通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。

  1. 从第一个元素开始,该元素可以认为已经被排序;
  2. 取出下一个元素,在已经排序的元素序列中从后向前扫描;
  3. 如果该元素(已排序)大于新元素,将该元素移到下一位置;
  4. 重复步骤3,直到找到已排序的元素小于或者等于新元素的位置;
  5. 将新元素插入到该位置后;
    重复步骤2〜5。
public static void insertionSort(int[] array) {
    int len = array.length;
    for (int i = 1; i < len; i++) {//从第二个数开始比较
        int temp = array[i];
        int index = i;
        for (int j = i - 1; j >= 0; j--) {
            if (array[j] > temp ) {
                array[j + 1] = array[j];////注意并不需要交换元素,只需要后移
                index = j;
            } else {
                break;//array[j+1]之前是有序序列,array[j] <= array[j+1]无须比较
            }
        }
        if (index != i){
        array[index] = temp;
    }
}

希尔排序

希尔排序也是一种插入排序,它是简单插入排序经过改进之后的一个更高效的版本,也称为缩小增量排序,同时该算法是冲破O(n2)的第一批算法之一。它与插入排序的不同之处在于,它会优先比较距离较远的元素。希尔排序又叫缩小增量排序。
希尔排序是把记录按下表的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一组,算法便终止。
我们选择增量gap=length/2,缩小增量继续以gap = gap/2的方式,这种增量选择我们可以用一个序列来表示,{n/2,(n/2)/2...1},称为增量序列,图解:


public static void shellSort(int[] array) {
    int len = array.length;
    for (int gap = len / 2; gap > 0; gap /= 2) {
        for (int i = gap; i < len; i++) {//直接插入排序
            int temp = array[i];
            int index = i;
            for (int j = i - gap; j >= 0; j -= gap) {
                if (array[j] > temp) {
                    array[j + gap] = array[j];
                    index = j;
                } else {
                    break;
                }
            }
            if (index != i) {
                array[index] = temp;
            }
        }
    }
}

快速排序

快排采用分治策略,从序列中选一个基准值,将小于基准值的元素排在左边,大于基准值元素排在右边,然后对这两个子序列进行递归,最终整个序列有序
待排序列为:
35 12 99 56 0 78
i → ............. ← j

  1. 取首位元素为基准值(最好取中间值),设置两个指针i,j,分别标识序列首末两个元素,i,j移动方向为i++,j--
  2. j位元素先和基准值比较,若大于基准值,j左移(j--),直到小于基准值,赋值,i右移一位
    0 12 99 56 0 78
    .....i ............j
  3. i位元素和基准值比较,若小于基准值,i右移(i++),直到大于基准值,赋值,j左移一位
    0 12 99 56 99 78
    ......... i ..j
    2.递归
public static void quickSort(int[] array) {
    int len = array.length;
    sort(array, 0, len - 1);
}
private static void sort(int[] src, int begin, int end){
    if (begin < end) {
        int key = src[begin];//将第一个数作为基准值
        int i = begin;
        int j = end;
        while (i < j) {
            while (i < j && src[j] >= key) {
                j--;
            }
            if (i < j) {
                src[i] = src[j];
                i++;
            }
            while (i < j && src[i] < key) {
                i++;
            }
            if (i < j) {
                src[j] = src[i];
                j--;
            }
        }
        src[i] = key;
        sort(src, 0, i - 1);
        sort(src, i + 1, end);
    }
}

各种排序的时间复杂度

相关文章

  • 数据结构&算法(一)

    一、Java实现快速排序算法 二、Java实现折半插入排序算法 三、Java实现冒泡排序算法

  • java 实现排序算法之「插入排序」

    java 实现排序算法系列 这是 Java 实现排序算法的第三篇文章——插入排序算法。插入排序可以说成是「一类」简...

  • 排序

    八大排序算法 一、归并排序 递归及非递归的JAVA实现 二、快速排序 快排算法JAVA实现 三、堆排序 堆排序堆排...

  • 一文搞定十大经典排序算法(Java实现)

    本文总结十大经典排序算法及变形,并提供Java实现。参考文章:十大经典排序算法总结(Java语言实现)快速排序算法...

  • 快速排序

    手写java版快速排序算法实现

  • 排序算法

    常见排序算法比较 参考资料:各种排序算法比较 参考资料:快速排序算法 必须知道的八大种排序算法【java实现】(一...

  • 排序算法最强总结及其代码实现(Python/Java)

    前言 本文总结了常用的全部排序算法,内容包括: 排序算法的定义和思路 排序算法的代码实现:Python和Java,...

  • 7大经典的排序算法总结实现

    作者 : 专注J2EE来源 : 博客园 常见排序算法总结与实现 本文使用Java实现这几种排序。以下是对排序算法总...

  • 【算法】排序(一)选择排序

    在排序算法中,最简单的莫过于选择排序了。 本文将介绍以下内容 排序思路算法实现(JAVA)测试阶段算法分析 排序思...

  • 常用数据结构及算法

    数据结构与算法——常用排序算法及其Java实现 - QueenKing - SegmentFault 思否

网友评论

      本文标题:排序算法(java实现)

      本文链接:https://www.haomeiwen.com/subject/ezdtnqtx.html