三种基础排序算法总结

一、冒泡排序

1、算法思想:

1)、两层循环,外层循环i从0开始,内层循环从j=i+1开始
2)、如果ary[i] < ary[j],则交换其值
3)、直到外层循环到length-1

2、主算法实现

public static void bubbleSort(int[] ary){
    int length = ary.length;  
    //每完成一轮外层循环,ary[i]的次序在全局确定
    for (int i = 0; i < length; i++) {
        //内层循环向后扫描,且立即交换。
        for (int j = i+1; j < length; j++) {
            if (ary[i] > ary[j]) {
                swap(ary, i, j);
            }
        }
    }
}

3、稳定性:

int[] ary = {3,2,2,0};
algoBubbleSort(ary);
for(int value:ary){
    System.out.println(value);//{0,2,2,3},此冒泡排序是非稳定的排序
}

二、选择排序

1、算法思想

1)、两层循环,外层循环i从0开始,内层循环j从i+1开始。
2)、用minIndex记录每轮内层循环的最小元素位置
3)、每轮内层循环完成后交换ary[minIndex]和ary[i]的值

2、主算法实现

    public static void selectionSort(int[] ary){
        int length = ary.length;
        int minIndex;
        //每完成一轮外层循环,ary[i]的次序在全局确定
        for (int i = 0; i < length; i++) {
            minIndex = i;
            for (int j = i+1; j < length; j++) {
                if (ary[minIndex] > ary[j]) {//非立即交换,只更小元素的记录位置
                    minIndex = j;
                }
            }
            //内层循环全部结束再交换
            swap(ary, i, minIndex);
        }
    }

3、稳定性

选择排序是非稳定的排序
例如对数组{2,2,3,0}排序后,重复元素2的原有相对位置被破坏。

三、插入排序

1、算法思想

1)、两层循环,外层循环i从0开始,内层循环j从i开始向前扫描
2)、如果ary[j] < ary[j-1],也即元素ary[j]的值严格小于ary[j-1]的值,就立即交换。否则break停止j的扫描。

2、算法实现

1)版本一:O(n^2)的交换时间复杂度

    public static void insertSort(int[] ary){
        int length = ary.length;
        for (int i = 0; i < length; i++) {
            for (int j = i; j > 0; j--) {
                //正确确定元素ary[j-1]的位置
                //如果ary[j-1]严格大于ary[j],就将ary[j-1]向前挪动
                if (ary[j] < ary[j-1]) {
                    swap(ary, j, j-1);
                }else{
                    break;
                }
            }
        }
    }

2)版本二:

    public static void insertSort(int[] ary){
        int length = ary.length;
        int tmp,position;
        for (int i = 0; i < length; i++) {
            position = i;
            tmp = ary[i];
            for (int j = i; j > 0; j--) {
                if (tmp < ary[j-1]) {
                    //挪动比tmp更大的元素,为tmp元素腾出位置。此时ary[j]和ary[j-1]相同
                    ary[j] = ary[j-1];
                    position = j-1;//更新其准确位置
                }else{
                    break;
                }
                ary[position] = tmp;//正确放置ary[position]
            }
        }
    }

3、稳定性:

插入排序是稳定的排序。

四、区别比较

1、冒泡排序
特点:内层循环j向后扫描,依次和ary[i]比较,遇到更小,则立即交换。
每完成一轮外层循环,ary[i]在全局得到最终的次序,且ary[i]之前元素的次序也是全局的次序,后序的排序过程已对其不再有影响。

2、选择排序
特点:
内层循环j同样向后扫描,依次和ary[i]比较,但是只记录更小元素的指针,最后才交换。
每完成一轮外层循环,ary[i]在全局得到最终的次序,且ary[i]之前元素的次序也是全局的次序,后序的排序过程已对其不再有影响。


3、插入排序
特点:
内层循环j向前扫描,依次和ary[i]比较,为ary[i]找到正确的位置。
每完成一轮外层循环,ary[i]得到的次序只能是局部的次序,未必是全局的最终次序。同时ary[i]之前的元素只能是局部的次序,后序的排序过程可能会发生改变。

原文地址:https://www.cnblogs.com/qcblog/p/7532170.html