几种简单排序算法

一. 冒泡排序(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 + " ");
        }
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值