`
iwebcode
  • 浏览: 2011041 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
文章分类
社区版块
存档分类
最新评论

排序算法

 
阅读更多

    稳定的排序:排序前后的相对顺序不改变:排序前若Ri排在Rj之前,排序之后仍然是这样。

    不稳定的排序:与稳定相反。

    内部排序:待排序数据存放于计算机随即存储器之中。

    外部排序:待排序数据存放于外存中。

    参考书目:数据结构C语言版,严蔚敏,吴伟民

    定义数据结构:

    #define MAXSIZE 20

    typedef int KeyType;

    typedef struct{

    KeyType key

    InfoType info;

    }RedType

    typedef struct{

    RedType r[MAXSIZE];

    int Length;

    }SqList;

    排序算法介绍:

    1)直接插入排序:讲一个记录直接插入到一个已排好的有序表中

    时间复杂度:o(n^2),比较量与移动量的时间复杂度都为:o(n^2)

    空间复杂度:只要一个临时存储空间

    算法:

    void InsertSort(SqList &L)

    {

    for(i=2;i<=L.length;++i)

    if LT(L.r[i].key,L.r[i-1].key){

    L.r[0] = L.r[i];

    L.r[i] = L.r[i-1];

    for(j = i-2;LT(L.r[0].key,L.r[j].key);--j)

    L.r[j+1] = L.r[j];

    L.r[j+1] = L.r[0];

    }

    }

    2)希尔排序:shell排序

    先将待排序列分成若干子序列分别进行直接插入排序,待这个序列基本有序的时候,再对全体数据进行一次直接插入排序。

    3)起泡排序:

    基本思想:若逆序则交换,每次沉出一个最大值或者最小值;若一趟起泡排序无交换,则排序结束。

    4)快速排序:源于起泡排序

    通过一趟排序将待排序记录分成独立的两部分,其中一部分的关键字均比另一部分大,则可分别对这两部分数据使用该办法继续排序,直到有序。

    5)选择排序:

    每一趟在待排序数据中选取最小(最大)的记录作为第??个元素

    每一趟在n-i+1个记录中选取关键字最小的记录作为有序序列的第i个元素

    6)堆排序:

    把数组构建成二叉堆----这只要增添一个长度为n+1的辅助空间,然后把原数组的元素依次插入到二叉堆即可。然后删除二叉堆的根,把它作为排序后的数组的第一个元素,然后使二叉堆的长度减1,并通过上移使得新得到的序列仍为二叉堆,再提取新二叉堆的第一个元素到新数组。依此类推,直到提取最后一个元素,新得到的数组就是排序后的数组。

    7)归并排序:

    归并:将两个有序序列归并成一个有序序列。每一次归并的复杂度:o(m+n)

    归并算法:

    void Merge(RedType SR[],Redtype &TR[],int i,int m,int n)

    {

    for(j = m+1,k=i;i <= m,j<=n;k++)

    {

    if(SR[i].key<SR[j].key) TR[k]=SR[i++];

    else TR[k] = SR[j++];

    }

    if(i<=m) TR[k++] = SR[i++];

    if(j<=n) TR[k++] = SR[j++];

    }

    2-路归并排序:将待排序列分成[n/2]组,每组两个数据(若n为奇数,则有一组数只有一个数据),两两归并,之后继续如此归并直到有序。

    一趟归并的复杂度为:o(n);需要归并的次数为o(log2(n)),故归并排序的复杂度为o(nlog2(n))

    8)基数排序:

    从低位到高位依次对Kj(j=d-1,d-2,…,0)进行箱排序。在d趟箱排序中,所需的箱子数就是基数rd,这就是"基数排序"名称的由来

    各排序算法的关系:

    直接插入排序————Shell排序

    起泡排序——————快速排序

    选择排序——————堆排序

    排序算法比较:

    排序算法

    平均时间

    最坏情况

    辅助存储

    简单排序

    O(n^2)

    O(n^2)

    O(1)

    快速排序

    O(nlog(n))

    O(n^2)

    O(log(n))

    归并排序

    O(nlog(n))

    O(nlog(n))

    O(n)

    堆排序

    O(nlog(n))

    O(nlog(n))

    O(1)

    基数排序

    O(d(n+rd))

    O(d(n+rd))

    O(rd)

    就平均时间性能而言,最好的是快速排序,但快速排序的最坏时间比归并和堆排序都要差。上表中的简单排序不包括希尔排序。

    快速排序、堆排序、希尔排序等时间性能好的排序算法都是不稳定的。

    1.稳定性比较

    插入排序、冒泡排序、二叉树排序、二路归并排序及其他线形排序是稳定的

    选择排序、希尔排序、快速排序、堆排序是不稳定的

    2.时间复杂性比较

    插入排序、冒泡排序、选择排序的时间复杂性为O(n2)

    其它非线形排序的时间复杂性为O(nlog2n)

    线形排序的时间复杂性为O(n);

    3.辅助空间的比较

    线形排序、二路归并排序的辅助空间为O(n),其它排序的辅助空间为O(1);

    4.其它比较

    插入、冒泡排序的速度较慢,但参加排序的序列局部或整体有序时,这种排序能达到较快的速度。

    反而在这种情况下,快速排序反而慢了。

    当n较小时,对稳定性不作要求时宜用选择排序,对稳定性有要求时宜用插入或冒泡排序。

    若待排序的记录的关键字在一个明显有限范围内时,且空间允许是用桶排序。

    当n较大时,关键字元素比较随机,对稳定性没要求宜用快速排序。

    当n较大时,关键字元素可能出现本身是有序的,对稳定性有要求时,空间允许的情况下,宜用归并排序。

    当n较大时,关键字元素可能出现本身是有序的,对稳定性没有要求时宜用堆排序

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics