基本排序算法

选择排序

实现原理

首先找到数组中最小的那个元素,其次,将它和数组的第一个元素交换位置(如果第一个元素就是最小的元素那么它就和自己交换)。再次,在剩下的元素中找到最小的元素,将它与数组的第二个元素交换位置。如此往复,直到将整个数组排序。

特点

  1. 运行时间与输入无关。为了找出最小的元素而扫描一遍数组并不能为下一遍扫描提供什么有用信息。
  2. 数据移动是最少的。每次交换都会改变两个数组元素的值,因此选择排序用了N次交换——交换次数和数组的大小是线性关系。

具体实现

    public static void sort(Comparable[] a){
        int N = a.length;
        for(int i = 0;i < N;i++){
            int min = i;
            for(int j = i + 1;j < N;j++){
                if(a[j].compareTo(a[min]) < 0){
                    min = j;
                }
            }
            Comparable temp = a[min];
            a[min] = a[i];
            a[i] = temp;
        }
    }

对于长度为N的数组,选择排序需要(N - 1) + (N - 2) + ... + 2 + 1 = N(N - 1) / 2 ~ N² / 2次比较和N次交换

插入排序

实现原理

将数组的第一个数认为是有序数组,从后往前(从前往后)扫描该有序数组,把数组中其余n-1个数,根据数值的大小,插入到有序数组中,直至数组中的所有数有序排列为止。

特点

  1. 与选择排序相同。当前索引左边的元素都是有序的,但是它们的最终位置并不确定。
  2. 与选择排序不同的是,插入排序所需的时间取决于输入中元素的初始顺序。

对于随机序列的长度为N且主键不重复的数组,平均情况下插入排序需要~N²/4次比较以及~N²/4次交换。最坏情况下需要~N²/2次交换和~N²/2次比较。

具体实现

    public static void insertSort(Comparable[] a){
        int N = a.length;
        for(int i = 0;i < N;i++){
            for(int j = i;j > 0 && a[j].compareTo(a[j - 1]) < 0;j--){
                Comparable temp = a[j];
                a[j] = a[j - 1];
                a[j - 1] = temp;
            }
        }
    }

希尔排序

实现原理

希尔排序是插入排序的一种又称“缩小增量排序”,是直接插入排序算法的一种更高效的改进版本。希尔排序是非稳定排序算法。希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一组,算法便终止。

插入排序适用于比较有序的序列,对于完全无序的序列,插入排序的表现不好。而分组排序则解决了这个问题,每一次将数组分为若干个数组,并对该数组进行间隔为h的插入排序。最后一次则是间隔为1的插入排序,此时大数基本在数组的右边,小的数字在数组的左边,减少了交换的次数。

具体实现

    public static void shellSort(Comparable[] a){
        int N = a.length;
        int h = 1;
        while(h < N / 3){
            h = h * 3 + 1;
        }
        while(h >= 1){
            for(int i = h;i < N;i++){
                for(int j = i;j >= h && a[j].compareTo(a[j - h]) < 0;j -= h){
                    Comparable temp = a[j];
                    a[j] = a[j - h];
                    a[j - h] = temp;
                }
            }
            h = h / 3;
        }
    }

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值