快速排序、表排序、基数排序

-快速排序

算法概述:与归并相似,分而治之
void Quicksort ( ElementType A[ ] , int N )
{
if ( n < 2 ) return ;
pivot = 从A[ ] 中选出一个主元;
将 S={ A[ ] \ pivot } 分成2个独立子集:
A1 = { a属于S | a <= pivot } 和
A3 = { a属于S | a >= pivot } ;
A[ ] = Quicksort( A1 , N1 )并 { pivot }并Quicksort( A2 , N2 ) ;
}

选主元:
取中位数
ElementType Median3 ( ElementType A[ ] , int Left , int Right )
{
int Center = ( Left + Right ) / 2 ;
if ( A[ Left ] > A[ Center ] )
Swap ( &A[ Left ] ) , &A[ Center ] ) ;
if ( A[ Left ] > A[ Right ] )
Swap ( &A[ Left ] ) , &A[ Right ] ) ;
if ( A[ Center ] > A[ Right ] )
Swap ( &A[ Center ] ) , &A[ Right ] ) ;

 Swap ( &A[ Center ] , &A[ Right - 1 ] ) ;    //  将pivot藏到右边
 
 return A[ Right - 1 ] ;    //   返回主元,它在Right - 1这个位置

}

子集划分
每次选定主元并完成子集划分后,主元插入的位置都是它的最终位置,它一次性放到了正确位置以后都不用移动
如果有元素正好等于pivot,停下来交换?不交换,继续移动指针?比较后选择交换
快速排序问题:该算法用到递归,对于小规模数据(比如小于100的数据)可能还不如插入排序快
所以,当递归的数据规模充分小,则停止递归,直接调用简单排序;在程序中定义一个Cutoff的阈值,小于该值则调用简单算法

算法实现:
void Quicksort ( ElementType A[ ] , int Left , int Right )
{
if ( Cutoff <= Right - Left ) {
Pivot = Median3 ( A , Left , Right ) ;
i = Left ; j = Right - 1 ; // 开始做子集划分
for ( ; ; ) {
while ( A[ ++ i ] < Pivot ) { }
while ( A[ - - j ] > Pivot ) { }
if ( i < j )
Swap ( &A[ i ] , &A[ j ] ) ;
else break ; // 子集划分结束
}
Swap ( &A[ i ] , &A[ Right - 1 ] ) ;
Quicksort ( A , Left , i - 1 ) ;
Quicksort ( A , i + 1 , Right ) ;
}
else
Insertion_Sort ( A + Left , Right - Left + 1 ) ; // 当超过Cutoff阈值,开始用简单排序
}

统一接口:
void Quick_Sort ( ElementType A[ ] , int N )
{
Quicksort( A , 0 , N - 1 ) ;
}

-表排序

待排元素不是简单的数字而是比较大的结构,移动元素步骤不能忽略不计
排序过程中不需要移动原始数据,而是移动指向它们的指针,这样的排序叫间接排序;
定义一个指针数组作为“表”(table),如果仅要求按顺序输出,则输出:
A[ table[0] ], A[ table[1] ], …… , A[ table[N-1] ]
物理排序:
N个数字的排列由若干个独立的环组成
将物理排序独立成若干个独立的操作,开辟一个临时空间,从环中取出一个元素暂时放入该空间,依次将该环中其他元素 一一放置到正确的位置,最后将取出的元素拿出放进环中最后空出来的位置。
最好情况:初始即有序
最坏情况:有N/2个环,每个环包含2个元素,这是需要3N/2次元素移动。(每移动一对元素要走三步)

-基数排序

桶排序 eg:有N个学生,他们的成绩是0到100之间的整数,如何在线性时间内将学生按成绩排序?
0到100之间一共有101(M)个成绩值,给每个成绩值建立一个桶,桶实际上是链表;每输入的一个同学的成绩,就按成绩将该同学放入相对于的链表中
void Bucket_Sort ( ElementType A[ ] , int N )
{
count[ ] 初始化 ;
while ( 读入1个学生成绩grade )
将该学生插入count[ garde ]链表;
for ( i = 0 ; i < M ; i ++ ) { // M是成绩值总数
if ( count[ i ] )
输出整个count [ i ]链表;
}
}

基数排序 eg:假设有N=10个整数,每个整数的值在0到999之间(于是有M=1000个不同的值)此时再用桶排序则不合算
基数是进制的基数,如0到999之间的数,最多是三位数,每个位上的基数有10种可能
输入序列:64,8,216,512,27,729,0,1,343,125
用“次位优先”(Least Significant Digit)即优先比较个位
建立0~9十个桶,第一趟排序按照每个数字个位上的数放入相应的桶,第二趟按十位上的数对应放入相应的桶,第三趟比百位数,
时间复杂度 T=O(P(N+B))
如果桶的数量足够小,整个复杂度是线性的

多关键字排序,如扑克牌按花色、面值两种关键字排序
多关键字可理解为多位数字,花色是十位,面值是个位
若用主位优先,分为四个桶,再在每个桶里按面值排序
次位排序更为便捷,为面值建立13个桶;将结果合并,然后再为花色建四个桶

-排序算法的比较:

简单排序:简单选择排序、冒泡排序、直接插入排序。
选择排序是跳着交换的,导致其不稳定性;简单排序时间复杂度较高,不过代码较简单,其中冒泡排序和直接插入排序是稳定的

希尔排序平均时间复杂度较低,但它的好坏取决于增量序列,不过最坏情况下时间复杂度依然是N的平方
堆排序和归并排序,理论上,时间复杂度都是 N*logN,其中堆排序的N可能很大,所以某些情况下会比快速排序要慢,且它是不稳定的;归并排序是稳定的,但需要一定空间;

快速排序是递归的,所以需要logN的空间复杂度,最坏情况下时间复杂度是N的平方,是不稳定排序

基数排序某些情况下近乎线性,取决于桶

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,033评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,725评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,473评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,846评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,848评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,691评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,053评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,700评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,856评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,676评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,787评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,430评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,034评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,990评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,218评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,174评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,526评论 2 343

推荐阅读更多精彩内容