几种简单排序算法

来源:互联网 发布:人类灭亡 知乎 编辑:程序博客网 时间:2024/05/07 12:36

一. 冒泡排序(Bubble Sort)

1. 优点:

简单.

2. 缺点

运行十分缓慢,效率低.

3. 思路:

这里写图片描述
点击此处,演示执行流程
 比较相邻两个队员. 如果左边高于右边, 交换位置, 否则不变. 一圈比较下来最高的跑到了最后面; 第二圈忽略最后面的那个数(因为它已经是最大的了), 再从左边开始比较相邻两个数…如此循环

4. 核心代码:

    public void testBubbleSort(){        int[] arr = {33,44,22,11,55};        // 外圈循环一次, 最大的"冒泡"到最后边        for(int i=0; i<arr.length-1; i++){            // 内圈循环是为了比较相邻两个数            for(int j=0; j<arr.length-i-1; j++){                if(arr[j]>arr[j+1]){                    // 交换位置                    int temp = arr[j];                    arr[j] = arr[j+1];                    arr[j+1] = temp;                }            }        }        for(int a : arr){            System.out.print(a+" ");        }    }

5. 时间复杂度

 假设有10个数, 第一圈比较9次, 第二圈比较8次…总共下来是:9+8+7+6+5+4+3+2+1=45次.
 一般来说, 数组中有N个数据项, 第一趟排序中有N-1次比较, 第二趟中有N-2次比较, 以此类推. 这种求和公式如下:

(N1)+(N2)+(N3)+...+1=N(N1)/2

 这样, 算法作了N^2次比较.(忽略减1,当N很大时,不会有很大差别)
 平均下来, 大约有一般的数据要进行交换, 则交换次数为N^2/4.(就算在最坏的逆序情况下,比较数等于交换数)
 无论何时,只要看到一个循环嵌套在另一个循环里, 例如在冒泡排序和其他排序中, 就可以怀疑这个算法的运行时间为O(N^2)级.这就意味着大约需要执行N*N或者N^2次某个基本操作.

二. 选择排序(Select Sort)

1. 优点

 改进冒泡排序, 将必要交换次数从O(N^2)减少到O(N).

2. 缺点

 比较次数仍然为O(N^2).

3. 思路

这里写图片描述
点击此处,演示执行流程
 把所有队员都扫描一遍, 从中挑出来最矮的一个队员. 让最矮的队员和最左边的队员交换位置.所以最左边的队员就是有序的了.注意:这个算法中有序的队员都排在队列的左边(较小的下标值), 而在冒泡排序中有序的是队列右边的数据.
 再次扫描队员时,就从1号位置开始(0号已是最矮), 还是寻找最矮的, 然后和1号位置队员交换. 这个过程一只持续到所有队员都排定.

注意:
 挑出来最小的, 并不是记录它的值, 而是记录下来他的索引位置, 然后和最左边的索引进行交换.

4. 核心代码

public void testSelectSort(){    int[] arr = {33,44,22,11,55};    // 外圈, 为了让左边和最小值进行交换(而寻找最小值是内圈的任务)    for(int i=0; i<arr.length-1; i++){        // 将最左边的索引记录给min        int min = i;        for(int j=i+1; j<arr.length; j++){            // 找出最小            if(arr[j]<arr[min]){                min = j;            }            // 交换位置            int temp = arr[min];            arr[min] = arr[i];            arr[i] = temp;        }    }    for(int each : arr){        System.out.print(each+" ");    }}

5. 时间复杂度

 选择排序和冒泡排序进行了相同次数的比较N*(N-1)/2. 对于10个数据项, 需要比较45次.然而, 10个数据项只需要少于10次的交换.
 当N值很大时, 比较次数是主要的, 所以结论是选择排序和冒泡排序一样运行了O(N^2)时间. 但是, 无疑是选择排序效率更高, 因为它的实际交换次数少.

三. 插入排序(Insert Sort)

1. 优点

 平均情况下,速度快于冒泡和选择(完全逆序除外).

2. 缺点

 较于冒泡和选择稍微复杂.

3. 思路

这里写图片描述
点击此处,演示执行流程
 取出一个(等待被插入)值赋值给一个临时变量, 然后将这个临时变量和它左边的值作比较, 如果左边的值大于这个临时值, 则将左边的值向右移动.否则就将临时值插入到这个位置. 一轮循环到此结束, 接下来再将上一个(等待被插入)的值的下一个值取出来作为新的(等待被插入的值),再次执行上边的步骤.如此循环, 直至全部有序.

举个例子: 就像整理书架上的书籍一样, 以几本有序的为基准, 将它右边的书本一本一本拿出来, 然后将有序的向右推, 将取出的书本插入到有序的合适的位置.(又有点像整理扑克牌一样)

4. 核心代码

public void testInsertSort(){        int i,j;        for(i=1;i<arr.length;i++){            // 记录下来被取出(等待被插入)的值            int temp = arr[i];            j=i;            // 拿这个被取出的值和它左边的值比较, 如果左边的值大于它,将左边的值向右移动一位            while(j>0&&arr[j-1]>=temp){                arr[j] = arr[j-1];                 --j;            }            // 最后将等待被插入的值插入到合适的索引位            arr[j] = temp;        }        for(int each: arr){            System.out.print(each + " ");        }    }
原创粉丝点击