数据结构排序
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
/* 对存放在数组array[]中,长度为n的序列排序 */
{ int i,j; NODE x;
for(i=1;i<n;i++)
{ x=array[i]; j=i-1;
while (j>=0 && x.key<array[j].key)
{ array[j+1]=array[j]; j--; }
array[j+1]=x;
}
}
9.1.2 希尔排序
希尔排序是一种步长递减的插入排序,又称为
“缩小增量排序”。该排序方法是,将直接插入分成插入 步长由大到小不同的若干趟来进行。初始,步长较大,相 当于把待排记录序列分成若干子序列,各子序列中记录的 间隔为步长距离,由于子序列的长度小,所以子序列的插 入排序的效率较高。以后各趟逐步减小步长,随着步长的 减小,子序列的长度在增加,但子序列中包含了上一趟经 过大的步长插入排序的结点,因此,已有部分结点有序, 这样,在排序中记录移动的次数就少,排序的效率也就高。 最后一趟是步长为1,即:对整个序列直接插入排序,但 这时整个序列已基本有序,只要做少量记录移动,就可将 该序列排成有序。
问题,但它的排序速度要比直接插 入排序快,另外,它是一种不稳定 排序
9.2 交换排序
交换排序基本思想:比较二个待排序记录的关键字, 若为逆序,则交换位置,反之,保持原序。
9.2.1 冒泡(简单交换排序)
冒泡排序的方法是:首先比较array[n-1].key和array[n-2]. key,若为逆序则交换之,然后比较array[n-2].key和array[n3].key,依此类推,直到比较array[1].key和array[0].key,称为 一趟“冒泡”,其结果是将具有最小关键字的记录排到序列 的第1个位置上。然后再array[n-1]到array[1]之间进行一趟“ 冒泡”,将具有次小关键字的记录排到序列的第2个位置上。 依此类推,直到第n-1趟,在array[n-1]和array[n-2]之间进行“ 冒泡”后,待排序序列已排成有序。
处理记录号 i=1 i=2 i=3 i=4 i=5 i=6 i=7
插入位置 j=0 j=0 j=0 j=1 j=0 j=4 j=2
下标 0 1 2 3 4 5 6 [91] 67 35 62 29 72 46 [67 91] 35 62 29 72 46 [35 67 91] 62 29 72 46 [35 62 67 91] 29 72 46 [29 35 62 67 91] 72 46 [29 35 62 67 72 91] 46 [29 35 46 62 67 72 91]
第9章 排 序
9.1 插入排序 9.2 交换排序 9.3 选择排序 9.4 归并排序 习题
• 排序是针对记录的集合{R1,R2,…,Rn},其相应的关键字 序列为{K1,K2,…,Kn},重组记录之间的关系,使记录的 排列次序满足相应的关键字的递增或递减关系。记录的集 合也称为待排序序列。若待排序序列完全存放在内存中, 则该排序称为内部排序;若由于数据集合太大,在排序过 程中,需对外存进行访问,则该排序称为外部排序。
{ for(i=step; i<n; i++)
{ x=array[i]; j=i-step;
while (j>=0 && x.key<array[j].key)
{ array[j+step]=array[j]; j=j-step;
} array[j+step]=x; } } }
希尔排序的分析是一个复杂的
• 有如下一组待排序序列(每个记录只列出关键字一项):
53,25,67(1),46,29,67(2),89,43,67(3),76
括号里的数字代表等值记录的位置,若排序后为:
25,29,43,46,53,67(1),67(2),67(3),76,89
则称所用的排序方法是稳定的,反之,若三个等值记录的 排列顺序不是上述顺序,就称所用排序的方法是不稳定的 。
图9.1 直接插入排序示例
例如,有一组关键字序列为{91,67,35,62,29,72,46},直接 插入排序过程如图9.1所示。
用C语言描述的直接插入排序算法如下:
typedef struct
{ int key;
…
/* 其他域 */
} NODE;
算法9.1 直接插入排序算法。
void InsertSort (NODE array[],int n)
9.1 插入排序
9.1.1 直接插入排序
它的基本操作是在处理第i个记录时,前面1到i-1记录已 排成有序,将第i个记录插入有序表中,得到一个新的有序 表,表的长度加1。当表中只有一个记录时,该表已是有序 表,所以,可以从第二个记录开始,逐个插入记录,直至处 理完待排序序列的所有记录。
直接插入排序的时间复杂度为O(n2),并且是一种稳定 排序。当n较小时,排序的效率较高,是一种常用的排序方 法
下一趟区间 下标 0 1 2 3 4 5 6
初始关键字 [6,0]
[91 67 35 62 29 72 46]
第一趟冒泡后 [6,1]
29 [91 67 35 62 46 72]
第二趟冒泡后 [6,2]
29 35 [91 67 46 62 72]
第三趟冒泡后 [6,3]
29 35 46 [91 67 62 72]
图9.2 希尔排序示例 例如,有8个关键字序列为{91,67,35,62,29百度文库72,46,57},插 入排序的步长序列为4,2,1。希尔插入排序过程如图9.2。
步长序列的选择没有严格的规定,只要该序列{d1, d2,…,dt}满足d1>d2>…>dt,并且当t≥1时,d1=1,该序 列都可选作步长序列。一般采用步长序列为d1=n/2, di+1=di/2(n为待排序序列的长度)。
用C语言描述的希尔排序算法如下:
算法9.2 希尔排序算法。
void ShellSort(NODE array[],int n)
/* 对存放在数组array[]中,长度为n的序列希尔排序 */
{ int i,j,step; NODE x;
for(step=n/2; step>0; step=step/2) /* step不断变小,直至为1 */