数据结构 八大排序算法

来源:互联网 发布:伴知旅行网 编辑:程序博客网 时间:2024/06/05 23:54

一、排序的分类

排序有内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存。




二、排序的复杂度稳定性

各种排序的稳定性,时间复杂度和空间复杂度:


我们比较时间复杂度函数的情况:


结论:所以对n较大的排序记录。一般的选择都是时间复杂度为O(nlog2n)的排序方法。

说明:1、当原表有序或基本有序时,直接插入排序和冒泡排序将大大减少比较次数和移动记录的次数,时间复杂度可降至O(n);

  2、快速排序则相反,当原表基本有序时,将蜕化为冒泡排序,时间复杂度提高为O(n2);

  3、原表是否有序,对简单选择排序、堆排序、归并排序和基数排序的时间复杂度影响不大。

选择:1、待排序的记录数目n的大小;

  2、记录本身数据量的大小,也就是记录中除关键字外的其他信息量的大小;

  3、关键字的结构及其分布情况;

  4、对排序稳定性的要求。

设待排序元素的个数为n.

1)当n较大,则应采用时间复杂度为O(nlog2n)的排序方法:快速排序、堆排序或归并排序序;

快速排序:目前基于比较的排序中被认为最好的方法,当待排序的关键字是随机分布时,快速排序的平均时间最短;

堆排序:  如果内存空间允许且要求稳定性的;

归并排序:有一定数量的数据移动,所以我们可能会与插入排序组合,先取定长序列,然后合并,效率上将有所提高。

2)当n较大,内存空间允许,且要求稳定性 =》归并排序;

3)当n较小,可采用直接插入或直接选择排序;

直接插入排序:当元素分布有序,直接插入排序将大大减少比较次数和移动记录的次数。

直接选择排序 :元素分布有序,如果不要求稳定性,选择直接选择排序

4一般不使用或不直接使用传统的冒泡排序;

5基数排序:它是一种稳定的排序算法,但有一定的局限性:

1、关键字可分解。

2、记录的关键字位数较少,如果密集更好

3、如果是数字时,最好是无符号的,否则将增加相应的映射复杂度,可先将其正负分开排序。


1.插入排序—直接插入排序(Straight Insertion Sort)

插入排序非常类似于整扑克牌。

在开始摸牌时,左手是空的,牌面朝下放在桌上。接着,一次从桌上摸起一张牌,并将它插入到左手一把牌中的正确位置上。为了找到这张牌的正确位置,

要将它与手中已有的牌从右到左地进行比较。无论什么时候,左手中的牌都是排好序的。



   
public class InsertSort {    public void sort(int[] arr) {        int i, j;        int n = arr.length;        int target;        for (i = 1; i < n; i++) {            j = i;            target = arr[i];            while (j > 0 && target < arr[j - 1]) {                arr[j] = arr[j - 1];                j--;            }            arr[j] = target;        }    }}



2.插入排序—希尔排序(Shell Sort)

基本思想:先将整个待排序的记录序列分割成为若干子序列分别进行直接插入排序,待整个序列中的记录“基本有序”时,再对全体记录进行依次直接插入排序。



    public static void sort(int[] a) {        int i, j;        int r, temp;        for (r = a.length / 2; r >= 1; r /= 2) {            for (i = r; i < a.length; i++) {                temp = a[i];                j = i - r;                while (j >= 0 && temp < a[j]) {                    a[j + r] = a[j];                    j -= r;                }                a[j + r] = temp;            }        }    }


3.选择排序—简单选择排序(Simple Selection Sort)

基本思想:在要排序的一组数中,选出最小(或者最大)的个数与第1个位置的数交换;然后在剩下的数当中再找最小(或者最大)的与第2个位置的数交换,依次类推,直到第n-1个元素(倒数第二个数)和第n个元素(最后个数)比较为止。


 


    public static void sort(int[] array) {        // minLoc用于记录i+1到args.length-1这个区间的最小值的下标(i会递增),i表示要交换的位置。        for (int i = 0, j = 0, minLoc = 0; i < array.length; i++) {            minLoc = i;            for (j = i + 1; j < array.length; j++) {// 找出i+1到args.length-1这个区间的最小值的下标                if (array[j] < array[minLoc]) {                    minLoc = j;                }            }            if (minLoc != i) {// 如果minLoc!=i,说明minLoc有变化,就进行交换                int temp = array[i];                array[i] = array[minLoc];                array[minLoc] = temp;            }        }    }


3.选择排序—堆排序(Heap Sort)




0 0
原创粉丝点击