zoukankan      html  css  js  c++  java
  • 常用排序算法总结(一)

    常见排序算法的复杂度

    一.冒泡排序

    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+",");
            }
        }
    }
  • 相关阅读:
    洛谷P3157 [CQOI2011]动态逆序对
    CDQ分治
    快速数论变换(NTT)
    洛谷P3338 [ZJOI2014]力
    洛谷 P1919 A*B Problem升级版
    0-1分数规划
    洛谷P4593 [TJOI2018]教科书般的亵渎
    拉格朗日插值
    20180912-3 词频统计
    20190912-1 每周例行报告
  • 原文地址:https://www.cnblogs.com/SitongLiu/p/6527613.html
Copyright © 2011-2022 走看看