排序入门笔记

排序是指按照一定的方法将无序或者有序的数组排列成有序的数组。这里以升序为例。

初等排序一共有两种排序方法,一种是选择排序一种插入排序:

首先介绍选择排序,选择排序的目标是每次选出最小、第二小、第三小。。。。。。第n小的元素放在第一个、第二个。。。。。。第n个元素的位置。

它的做法是从0开始选取一个最小的元素,与第0个元素交换。那么现在可以保证第0个元素是在0-n个元素中最小的元素,那么第二小的元素可以从1-n中的元素寻找。继续重复前面的步骤,第二小的元素就放在了第二个,那么第三小的元素就可以从2-n的元素中寻找。如此反复直到最后。代码如下所示

复制代码
 1     public void SeletInset(int[] nums) {
 2         for(int i = 0; i < nums.length; i++){                                                                                                                                                                                                                                                                                                                                                                                                                                              
 3                 int min = i;
 4                 for (int j = i + 1; j < nums.length; j++) {
 5                     if (less(nums[j], nums[min]))
 6                         min = j;
 7                 }
 8                 exchange(nums, i, min);
 9         }
10     }
复制代码

评价排序算法效率的标准有两个:一个是比较次数,所谓排序必须要对各个元素的主键进行比较,比较次数的规模很大程度上影响了排序效率。第二个是交换次数,若元素原本就处在正确的位置上有些算法不需要进行交换而有些算法则需要交换若干次再回到正确的位置,这也是评价排序效率的重要标准。

由代码可知选择排序的特点有两个,第一个是比较次数与初始状态无关,无论初始状态是否有序,都需要比较n²/2次。第二个则是交换次数可以是0~n次。换而言之,影响选择排序效率的主要因素是比较次数,而数组的初始状态与运行时间没有关系,

第二个是插入排序,插入排序的思路是保证第1到第i个元素有序(i从1到n-1)的情况下将第i+1个元素插入前i个元素保证有序,如此反复,重复n-1次。代码如下

    public void InsertSort(int[] nums) {

        for(int i = 1; i < nums.length; i++)
            for(int j = i; j > 0 && less(nums[j], nums[j-1]); j--){
                exchange(nums, j, j - 1);
            }
    }

插入排序的比较次数最多n²/2次比较,最好情况需要进行n-1次比较,平均需要n²/4次比较。最好情况不需要交换,最坏情况需要与平均情况和比较次数相同。

下面简单介绍一下插入排序的进化版,希尔排序。思路是将数组中间隔若h元素的元素作为一个集合,称为h数组,对h数组进行插入排序保证所有h数组有序。h的大小自定义。代码如下

复制代码
    public int ShellSort(int[] nums){
        int count = 0;
        int h = 1;
        int flag = nums.length/3;
        while(h < flag) h = h * 3 + 1;
        while(h >= 1){
            for(int i = h; i < nums.length; i++){
                for(int j = i; j >= h && less(nums[j], nums[j-h]); j -= h){
                    exchange(nums, j, j-h);
                    count ++;
                }
            }
            h = h/3;
        }
        return count;
    }
复制代码

可以由各种数学证明得知希尔排序的时间复杂度与n的3/2次方成正比。希尔排序对于中等输入的规模有着比较好的效果,有时也可以作为复杂排序算法的中间算法进行过渡。                                                                                                                                                                                                                                                                                   

posted @   Yeqsy  阅读(44)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
点击右上角即可分享
微信分享提示