排序算法整理(Java)

1. 直接插入排序(Insert Sort)

1.1 思路:

1.将待排序序列分为有序区和无序区,初始时,有序区为待排序记录第一个,无序区为剩下所有。
	2.将无序区的第一个记录插入到有序区合适位置中,无序区记录减一,有序区加一。
	3.重复步骤2,到无序区没有记录为止。
算法适用于少量数据的排序,时间复杂度为O(n^2),是稳定的排序方法。

1.2 算法实现

/**
     * 插入排序算法
     * 1.将数组分为有序区和无序区,初始有序区为数组第一个记录,无序区为剩下的记录。
     * 2.将无序区第一个记录插入到有序区的合适位置,有序区增加一个记录,无序区减少一个记录
     * 3.重复步骤二,直至无序区无记录。
     * @param array
     */
    public static void InsertSort(int [] array){
        for (int i = 1; i < array.length; i++) {//第一次比较
            int temp = array[i];                //记录下a[1]的值 a[1] = 64 ,无序区第一位
            int j = i;                          // j=1
            while ( j>0 && temp < array[j-1]){  //比较 有序区第一位 无序区第一位  即a[1] < a[0]时,数据前移一位    j>0 防止数据下标溢出
                array[j] = array[j-1];          //a[1] = a[0]
                j--;                            // j=0
            }
            array[j] = temp;                    //把a[1] 的值存储到 a[0]  交换完成
        }                                       //之后第二次  i=2 比较部分执行两次 因为有序区有两个元素,如此类推,最后完成排序
        //printArray(array);
    }

2.希尔排序(Shell Sort)

2.1 思路:

基本上和插入排序相同
区别:每次循环的步长,通过减半的方式来实现
说明:基本原理和插入排序类似,不一样的地方在于。通过间隔多个数据来进行插入排序。
算法适用于少量数据的排序,时间复杂度为取决于n,是不稳定的排序方法。

2.2算法实现

/**
     * 基本上和插入排序相同
     * 	区别:每次循环的步长,通过减半的方式来实现
     * 	说明:基本原理和插入排序类似,不一样的地方在于。通过间隔多个数据来进行插入排序。
     * 	算法适用于少量数据的排序,时间复杂度为取决于n,是不稳定的排序方法。
     * @param arry
     */
    public static void ShellSort(int [] arry){
        for (int i = arry.length / 2; i > 0; i /= 2) {
            //i层循环控制步长
            for (int j = i; j < arry.length; j++) {
                //j控制无序端的起始位置
                for (int k = j; k > 0  && k - i >= 0; k -= i) {
                    if (arry[k] < arry[k - i]) {
                        int temp = arry[k - i];
                        arry[k - i] = arry[k];
                        arry[k] = temp;
                    } else {
                        break;
                    }
                }
            }
            //j,k为插入排序,不过步长为i
        }
        printArray(arry);
    }

3.冒泡排序(Bubble Sort)

3.1 思路:

1.第一位开始,相邻两位比较,若后一位小于前一位就交换位置,否则不变。
 	2.每循环一个size长度次数,最后一位一定为最大。
 	3.即所需循环次数每次-1。

时间复杂度为O(n^2),是稳定的排序方法。

3.2算法实现

/**
     * 冒泡排序
     * 相邻两位比较,若后一位小于前一位就交换位置,否则不变。
     * 每循环一个size长度次数,最后一位一定为最大
     * @param array
     */
    public static void BubbleSort(int [] array){
        for (int i = 0; i < array.length-1; i++) {      //第一次循环 i=0时,比较n次,最后一位保证为最大值
            for (int j =0; j<array.length-1-i;j++) {    //第二次循环 i=1时,最后一位确定为最大值,只需要比较n-1次
                if (array[j] > array[j + 1]) {          // a[0] 和 a[1] 比较,大于则交换位置,小于则不变
                    int temp = array[j + 1];
                    array[j + 1] = array[j];
                    array[j] = temp;
                }
            }
        }
        //printArray(array);
    }

4.快速排序(Quick Sort)–是冒泡排序的改进版

4.1 思路:

基本思想:首先选择一个轴值(provit),将待比较序列分成独立的两个部分。
左侧记录的关键码都小于或等于轴值,右侧都大于或等于轴值。
然后分别对这两个子序列重复上述过程。

时间复杂度为O(n(log2)n),是不稳定稳定的排序方法。

4.2 算法实现

3.1 首先进行一次划分算法,将待排序序列分为两个部分。
/**
     * 一次排序算法
     * @param array
     * @param begin
     * @param end
     * @return
     */
    public static  int Partition(int [] array, int begin,int end) {
        int i=begin;
        int j=end;
        while (i<j){                    //第一次排序         i=0 j=6
            //对右侧扫描
            while (i<j && array[i] <= array [j]){      //if i<j a[i]<=a[j]成立 则j坐标前移一位
                j--;
            }
                int temp = array[i];                   //if a[i]<=a[j]不成立 则交换两坐标值
                array[i] = array[j];
                array[j] = temp;
                if (i<j){                              //且i坐标后移一位
                i++;
            }

            //同理对右侧扫描
            while (i<j && array[i] <= array[j]){
                i++;
            }
            if (i<j){
                int temp1 = array[i];
                array[i] = array[j];
                array[j] = temp1;
                j--;
            }
        }
        return i;           //返回轴点
    }
2.快速排序算法
/**
     * 快速排序
     * @param array
     */
    public static void QuickSort(int [] array){
        int begin = 0;
        int end = array.length-1;
        if (begin<end){
            int pivote = Partition(array,0,6);      //调用 进行第一次排序,得到轴点且根据轴点分为左右两侧两个子序列
            Partition(array,begin,pivote-1);              //对左侧子序列进行排序
            Partition(array,pivote+1,end);              //对右侧子序列进行排序
        }
        printArray(array);

    }