常用排序算法总结(一)

常见排序算法的复杂度

一.冒泡排序

1.时间复杂度为O(n^2)。
2.基本思路:

 第一趟:依次比较0和1、1和2、2和3…n-2和n-1索引的元素。如果发现第一个数据大于后一个数据,交换它们,经过第一趟,最大的元素排到了最后。

 第二趟:依次比较0和1,1和2、2和3…n-3和n-2索引的元素,如果发现第一个数据大于后一个数据,交换它们,经过第2趟,第2大的元素排到了倒数第2位。

 第n-1趟:依次比较0和1元素,如果发现第一个数据大于后一个数据,交换它们,经过第n-1趟,第2小(第n-1大)的元素排到了第2位。

3.例子:9,16,27,23,30,49,21,35 

 第一趟:9比16小,则不交换,16小于27不交换,27大于23则交换,此时变成9,16,23,27,30,49,21,35。接着27小于30,不交换。30小于49,不交换。49大于 21交换。此时顺序变成了9,16,23,27,30,21,49,35。49大于35,则交换。此时顺序变成9,16,23,27,30,21,35,49。第一趟排序结束,最大数49在最后面。
 
 第二趟:由9到30都是前面小于后面则不交换,到30和21位置,30大于21,交换。此时顺序,9,16,23,27,21,30,35,49. 30小于35,不再交换。第二趟结束。
 
 第三趟:9,16,23,21,27,30,35,49
             
 第四趟:9,16,21,23,27,30,35,49
 
package B;

/**
 * Created by LiuSitong on 2017/3/9.
 */
public class BubbleSort
{
    public void bubbleSort(int a[]){
        boolean flag = false;
        for (int i=0;i<a.length-1;i++){
            for (int j=0;j<a.length-1-i;j++ ){  //a.length-1-i 表示已经比较过的就不用再比较了
                //两个数进行交换
                int temp = 0;
                if (a[j]>a[j+1]){   //如果前一个数大于后一个数就交换
                    temp = a[j + 1];
                    a[j + 1] = a[j];
                    a[j] = temp;
                    flag = true;
                }
            }
            if (!flag)
            {
                break;
            }
        }
    }

    public static void main(String[] args) {
        int [] a  = {9,16,27,23,30,49,21,35};
        BubbleSort b = new BubbleSort();
        b.bubbleSort(a);
        for (int aa : a){
            System.out.print(aa+",");
        }
    }

}

二.快排

1.时间复杂度:O(nlgn)

2.快排思想是来自冒泡排序,冒泡排序是通过相邻元素的比较和交换把最小的冒泡到最顶端,而快速排序是比较和交换小数和大数,这样一来不仅把小数冒泡到上面同时也把大数沉到下面。

3.基本思路:

    第一步:设置两个变量I、J,排序开始的时候I=0,J=N(数组的最大索引号);

    第二步:以第一个数组元素作为关键数据,赋值给X,即X=A[0];

    第三步:从J开始向前搜索,即由后开始向前搜索(J=J-1),找到第一个小于X的值,两者交换;

    第四步:从I开始向后搜索,即由前开始向后搜索(I=I+1),找到第一个大于X的值,两者交换;

     第五步:重复第3、4步,直到I=J;

4.例子:49 38 65 97 76 13 27  (升序排列)

         以49为关键数据,开始从后面开始找 小于49 则交换   现在顺序是27 38 65 97 76 13 49 。交换后从前面往后找比49大的数,49 和65 交换 。然后再次从后面找,以次规律循环  当i == j时候 停止。第一次查找结束。

   第一次排序后,进行一次划分为  【27 38 13】 49 【76 97 65】

   最后结果:13,27,38,49,65,76,97

package B;

/**
 * Created by LiuSitong on 2017/3/9.
 */
public class QuickSort {
    public void  quickSort(int []data,int left,int right){
        int i = left;
        int j = right;

        if (i >= j){   //判断是否到了中间,到了中间就返回
            return;
        }

        boolean flag=true; //false:左->右  true:右->左
        while (i != j) { //如果i==j证明第一趟结束,每趟的标准值仅是一个,例如第一趟被比较值为49,
            if (data[i] > data[j]) {

                //交换数字 :所有比它小的数据元素一律放到左边,所有比他大的数据元素一律放到右边,
                int temp = data[i];
                data[i] = data[j];
                data[j] = temp;
                //只有经过数的交换后,才能把游标的移动位置改变,移动书序是交替改变
                //决定下标移动,还是上标移动 ,游标更改 走下一个数据
                // flag = (flag == true) ? false : true;
                flag=!flag;
            }
            //将指针向前或者向后移动 ,第一次从左-》右,第二次从右-》左
            if(flag) {//true,右---》左
                j--;
            }else{//false 左---》右
                i++;
            }
        } //1 2
        //到此,数组的数据排列位置为:
        //第一次到该位置,data的值是:[27, 38, 13, 49, 76, 97, 65]
        //将数组分开两半,确定每个数字的正确位置
        //i=3,j=3
        i--; //
        j++;
        //i=2 j=4 start=0 end=6
        quickSort(data, left, i); //也就是 27 38 13在快速排序
        quickSort(data, j, right); // 也就是 76, 97, 65在快速排序
    }



    public static void main(String[] args) {
        int [] a = {49,38,65,97,76,13,27};
        QuickSort q = new QuickSort();
        q.quickSort(a,0,a.length-1);
        for (int aa: a) {
            System.out.printf(aa+",");
        }
    }
}
原文地址:https://www.cnblogs.com/SitongLiu/p/6527613.html