几种常用排序整理

Posted youdiaodaxue16

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了几种常用排序整理相关的知识,希望对你有一定的参考价值。

排序分为内排和外排:

三种基本的内排算法:

1.插入排序:

有一个已经有序的数据序列,要求在这个已经排好的数据序列中插入一个数,但要求插入后此数据序列仍然有序,而插入排序的基本操作就是将一个数据插入到已经排好序的有序数据中,从而得到一个新的、个数加一的有序数据,算法适用于少量数据的排序。插入算法把要排序的数组分成两部分:第一部分包含了这个数组的所有元素,但将最后一个元素除外(让数组多一个空间才有插入的位置),而第二部分就只包含这一个元素(即待插入元素)。在第一部分排序完成后,再将这个最后元素插入到已排好序的第一部分中。

插入排序的基本思想是:每步将一个待排序的记录,按其关键码值的大小插入前面已经排序的文件中适当位置上,直到全部插入完为止。
 
举一个例子来说明:
        0  1  2  3  4  5  6  7  8  9  0

 

         4  8  2  0  9  5  7  1  5  6  3

       (4)(8  2  0  9  5  7  1  5  6  3)  //第一趟

          (4    8)    (2   0  9  5  7  1  5  6  3)    //第二趟

         (2  4  8)  (0  9  5  7  1  5  6  3)    //第三趟

         (0  2  4  8)  (9  5  7  1  5  6  3)    //第四趟

                     .......

是稳定的排序算法。时间复杂度的基本运算如果按比较和移动相同的话,则,时间复杂度固定为O(n*(n-1)/2)  =>O(n*n)。

最优的情况和最差的情况相同:

最优的情况(完全顺序),则,比较次数最多,移动次数为0;

最差的情况(完全逆序),则,比较次数最少,移动次数最多。

实现代码如下:

 

 1 void insertSort(int *data,int count){
 2     int fi;
 3     int j;
 4     
 5     for(fi = 1;fi < count; fi++){   //无序数组 
 6         int i ;
 7         int tmp = data[fi];            //有序数的数组data[]; 
 8         for(i = 0;i < fi;i++){
 9             if(data[i] > tmp){   //需要插入的data[i]和有序的tmp比较; 
10                 break;
11             }
12             for(j = fi;j > i;j--){    //移动 
13                 data[j] = data[j-1];
14             }
15             data[i] = tmp;
16         }
17     }
18 } 

 

2.选择排序:

选择排序(Selection sort)是一种简单直观的排序算法。它的工作原理是每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,直到全部待排序的数据元素排完。

举个例子来说明:

       4  7  2  5  9  1  5  8  6  3

       () (4  7  2  5  9  1  5  8  6  3)  //第一趟

      (1)(7  2  5  9  4  5  8  6  3)    //第二趟

      (1  2)(7  5  9  4  5  8  6  3)    //第三趟

      (1  2  3)(5  9  4  5  8  6  7)    //第四趟

              ........

 

稳定性分析:

 

选择排序是给每个位置选择当前元素最小的,比如给第一个位置选择最小的,在剩余元素里面给第二个元素选择第二小的,依次类推,直到第n-1个元素,第n个元素不用选择了,因为只剩下它一个最大的元素了。那么,在一趟选择,如果一个元素比当前元素小,而该小的元素又出现在一个和当前元素相等的元素后面,那么交换后稳定性就被破坏了。比较拗口,举个例子,序列5 8 5 2 9,我们知道第一遍选择第1个元素5会和2交换,那么原序列中两个5的相对前后顺序就被破坏了,所以选择排序是一个不稳定的排序算法。
 
算法时间复杂度:O(n(n - 1)/2) => O(n*n).
 
最优情况(完全顺序):时间复杂度只在于交换次数
最差情况(某种顺序):时间复杂度也只在于交换次数
 

 

代码如下:
 1 void chooseSort(int *data,int count){
 2     int index;
 3     int i ;
 4     int minIndex;
 5     int tmp;
 6     
 7     for(index = 0;index < count - 1;index++){        //遍历整个数组 
 8         for(minIndex = i = index;i < count;i++){    //拿出未排序第一个数与后面的数比较 
 9             if(data[minIndex] > data[i]){          //找到最小的 就是拿出来的那个数 
10                 minIndex = i;
11             }
12         }
13         if(minIndex != index){        //若拿出来的数不是最小的 
14             tmp = data[index];            //把拿出的这个数和后面比较出来最小的交换。 
15             data[index] = data[minIndex];
16             data[minIndex] = tmp;
17         }
18     }
19 }

3.直接交换排序

所谓交换,就是根据序列中两个记录键值的比较结果来对换这两个记录在序列中的位置,交换排序的特点是:将键值较大的记录向序列的尾部移动,键值较小的记录向序列的前部移动。

 

 

举个例子来说明:

        6  9  2  0  8  1  7  2  3  5  4

        6  2  0  8  1  7  2  3  5  4  9

        2  6  6  1  7  2  3  5  4  8  9

                                  ..........

稳定性:

由于在直接选择排序中存在着不相邻元素之间的互换,因此,直接选择排序是一种不稳定的排序方法。

时间复杂度:

在直接选择排序中,共需要进行n-1次选择和交换,每次选择需要进行 n-i 次比较 (1<=i<=n-1),而每次交换最多需要3次移动,因此,总的比较次数C=(n*n - n)/2,
总的移动次数 3(n-1).由此可知,直接选择排序的时间复杂度为 O(n2) ,所以当记录占用字节数较多时,通常比直接插入排序的执行速度快些。
代码如下:
 1 void swapSort(int * data;int count){
 2     boolean swap = TRUE;
 3     int tmp;
 4     
 5     for(int i = 0;swap&&i < n-1;i++){
 6         for(swap = FALSE,j = 0;j < n-1-i;j++){
 7             if(data[j] > data[j+1]){
 8                 tmp = data[j];
 9                 data[j] = data[j+1];
10                 data[j+1] = tmp;
11                 swap = TRUE;
12             }
13         }
14     } 
15 } 

 


以上是关于几种常用排序整理的主要内容,如果未能解决你的问题,请参考以下文章

常用python日期日志获取内容循环的代码片段

PHP 几种常用的算法整理

吐血整理Python 常用的几种高阶函数和简单的迭代函数

C#常用代码片段备忘

最全最详细publiccms常用的代码片段

最全最详细publiccms其他常用代码片段(内容站点)