第十章C交换排序

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

第 三 趟 排 序 后
第 四 趟 排 序 后
第 五 趟 排 序 后
第 六 趟 排 序 后
起泡排序示例
4
起泡排序算法 BUBBLESORT(rectype R[]) i,j,noswap; { int i,j,noswap; temp; rectype temp; (i=0 i<nfor (i=0;i<n-2;i++) noswap=TRUE; { noswap=TRUE; (j=n- j>=i; for (j=n-1;j>=i;j++) (R[j+1 key<R[j]. if (R[j+1].key<R[j].key) temp=R[j+1 { temp=R[j+1]; R[j+1]=R[j]; R[j+1]=R[j]; R[j]=temp; R[j]=temp; noswap=FALSE; noswap=FALSE; } break; if (noswap) break; } }
8
算法10.6(a)如下: 如下: 算法 如下 int Partition (SqList &L, int low, int high) { //交换顺序表 中子表 交换顺序表L中子表 的记录, 交换顺序表 中子表L.r[low..high]的记录,使枢轴记录到位,并返回其 的记录 使枢轴记录到位, //所在位置,此时在它之前(后)的记录均不大于(小)于它. 所在位置, 的记录均不大于( 于它. 所在位置 此时在它之前( pivotkey = L.r[low].key; //用子表的第一个记录作枢轴记录 用子表的第一个记录作枢轴记录 while (low < high) { //从表的两端交替地向中间扫描 从表的两端交替地向中间扫描 while (low < high && L.r[high].key >= pivotkey) ――high; L.r[low]←→L.r[high]; //将比枢轴记录小的记录交换到低端 将比枢轴记录小的记录交换到低端 while (low < high && L.r[high].key <= pivotkey) ++ low; L.r[low]←→L.r[high]; //将比枢轴记录大的记录交换到高端 将比枢轴记录大的记录交换到高端 } // while return low; } // Partition
7
一趟快速排序的具体做法是:附设两个指针 一趟快速排序的具体做法是:附设两个指针low和high,它们的初值分别为 和 , low和high,设枢轴记录的关键字为 和 ,设枢轴记录的关键字为pivotkey,则首先从 ,则首先从high所指位置起向前搜 所指位置起向前搜 找到第一个关键字小于pivotkey的记录和枢轴记录互相交换,然后从 的记录和枢轴记录互相交换, 索,找到第一个关键字小于 的记录和枢轴记录互相交换 然后从low所 所 指位置起向后搜索,找到第一个关键字大于pivotkey的记录和枢轴记录互相交 指位置起向后搜索,找到第一个关键字大于 的记录和枢轴记录互相交 重复这两步直至low=high为止.其算法如算法 为止. 所示. 换,重复这两步直至 = 为止 其算法如算法10.6(a)所示. 所示
总的时间复杂度为O(n2). 总的时间复杂度为 .
6
(2)快速排序 )
快速排序( 快速排序(Quick Sort)是对起泡排序的一种改进. )是对起泡排序的一种改进. ① 主要思想 快速排序的主要思想是:通过一趟排序将待排序记录分割成独立的两部分, 快速排序的主要思想是:通过一趟排序将待排序记录分割成独立的两部分, 其中一部分记录的关键字均比另一部分记录的关键字小, 其中一部分记录的关键字均比另一部分记录的关键字小,则可分别对这两部分 记录继续进行排序,以达到整个序列有序. 记录继续进行排序,以达到整个序列有序. ② 一趟快速排序 假设待排序序列为{L.r[s], L.r[s+1], … , L.r[t]},首先任意选取一个记录(通 首先任意选取一个记录( 假设待排序序列为 首先任意选取一个记录 常可选为第一个关键字L.r[s])作为枢轴(或支点)( 枢轴( )(pivot),然后按下述原 ),然后按下述原 常可选为第一个关键字 )作为枢轴 或支点)( ), 则重新排列其余记录:将所有关键字较它小的记录都安置在它的位置之前, 则重新排列其余记录:将所有关键字较它小的记录都安置在它的位置之前,将 所有关键字较它大的记录都安置在它的位置之后.由此可以该"枢轴" 所有关键字较它大的记录都安置在它的位置之后.由此可以该"枢轴"记录最后 落的位置i作分界线 将序列{L.r[s], … , L.r[t]}分割成两个子序列 作分界线, 落的位置 作分界线,将序列 分割成两个子序列 {L.r[s], L.r[s+1], … , L.r[i-1]}和{L.r[i+1], L.r[i+2], … , L.r[t]}.这个过程称做 - 和 + . 一趟快速排序(或一次划分). 一趟快速排序(或一次划分).
49
i
38
65
97
76
13
27
j
49
j
27
i
38
65
i
97
76
13
j
49
27 27 27
38
i
97 13
i
76 76
13
j
65
j
49 49 49
38 38
97
i
65
j
13
i j
76
97
j
65
27
38
13
49
76
97
65
49
12
一趟快排过程
2
£10.3 快速排序
(1)起泡排序 ) 起泡排序( 起泡排序(Bubble Sort)的过程: )的过程: 首先将第一个记录的关键字和第二个记录的关键字进行比较,若为逆序( 首先将第一个记录的关键字和第二个记录的关键字进行比较,若为逆序(L.r[1].key > L.r[2].key),则将两个记录交换之, ),则将两个记录交换之 ),则将两个记录交换之, 然后比较第二个记录和第三个记录的关键字. 然后比较第二个记录和第三个记录的关键字. 依次类推,直至第n-1个记录和第 个记录的关键字进行过比较为止. 个记录和第n个记录的关键字进行过比较为止 依次类推,直至第 个记录和第 个记录的关键字进行过比较为止. 上述过程称做第一趟起泡排序, 上述过程称做第一趟起泡排序, 其结果使得关键字最大的记录被安置到最后一个记录的位置上. 其结果使得关键字最大的记录被安置到最后一个记录的位置上. 一般地, 趟起泡排序是从 趟起泡排序是从L.r[1]到L.r[n-i+1]依次比较相邻两个记录的关键字,并 依次比较相邻两个记录的关键字, 一般地,第i趟起泡排序是从 到 + 依次比较相邻两个记录的关键字 逆序"时交换相邻记录,其结果是这n-i+ 个记录中关键字最大的记录被交换到 在"逆序"时交换相邻记录,其结果是这 +1个记录中关键字最大的记录被交换到 的位置上. 第n-i+1的位置上. 的位置上 整个排序过程需要进行k( 整个排序过程需要进行 (1≤k<n)趟起泡排序,显然 判别起泡排序结束的条件应该 )趟起泡排序,显然,判别起泡排序结束的条件应该 在一趟排序过程中没有进行过交换记录的操作" 是"在一趟排序过程中没有进行过交换记录的操作".
第十章
内部排序
£10.5 归并排序 £10.6 基数排序
£10.6.1 多关键字的排序 £10.6.2 链式基数排序
£10.1 概述 £10.2 插入排序
£10.2.1 直接插入排序 £10.2.2 其他插入排序 £10.2.3 希尔排序
£10.3 快速排序 £10.4 选择排序
£10.4.1 简单选择排序 £10.4.2 树形选择排序 £10.4.3 堆排序
10
算法10.6(b)如下: 如下: 算法 如下 int Partition (SqList &L, int low, int high) { //交换顺序表 中子表 交换顺序表L中子表 的记录, 交换顺序表 中子表L.r[low..high]的记录,使枢轴记录到位,并返回其 的记录 使枢轴记录到位, //所在位置,此时在它之前(后)的记录均不大于(小)于它. 所在位置,此时在它之前( 的记录均不大于( 于它. 所在位置 L.r[0] = L.r[low]; //用子表的第一个记录作枢轴记录 用子表的第一个记录作枢轴记录 pivotkey = L.r[low].key; //枢轴记录关键字 枢轴记录关键字 while (low < high) { //从表的两端交替地向中间扫描 从表的两端交替地向中间扫描 while (low < high && L.r[high].key >= pivotkey) ――high; L.r[low] = L.r[high]; //将比枢轴记录小的记录交换到低端 将比枢轴记录小的记录交换到低端 while (low < high && L.r[high].key <= pivotkey) ++ low; L.r [high] = L.r[low]; //将比枢轴记录大的记录交换到高端 将比枢轴记录大的记录交换到高端 } // while L.r[low] = L.r[0]; return low; } // Partition
11
例如, 例如,以式
R(49), R(38), R(65), R(97), R(76), R(13), R(27), R(49),
pivotkey
中关键字为例,一趟快速排序的过程如图 所示. 中关键字为例,一趟快速排序的过程如图10.7(a)所示. 所示
[初始关键字 初始关键字] 初始关键字 进行1次交换后 进行 次交换后 进行2次交换后 进行 次交换后 进行3次交换后 进行 次交换后 进行4次交换后 进行 次交换后 完成一趟排序 (a)
9
具体实现上述算法时,每交换一对记录需进行 次记录的移动 赋值) 次记录的移动( 具体实现上述算法时,每交换一对记录需进行3次记录的移动(赋值)的操 而实际上,在排序过程中对枢轴记录的赋值是多余的, 作.而实际上,在排序过程中对枢轴记录的赋值是多余的,因为只有在一趟排 序结束时, low=high的位置才是枢轴记录的最后位置 由此可改写上述算法, 的位置才是枢轴记录的最后位置. 序结束时,即low=high的位置才是枢轴记录的最后位置.由此可改写上述算法, 先将枢轴记录暂存在r[0]的位置上,排序过程中只作 的位置上, 的单向移动, 先将枢轴记录暂存在 的位置上 排序过程中只作r[low]或r[high]的单向移动, 或 的单向移动 直至一趟排序结束后再将枢轴记录移至正确位置上.如算法10.6(b)所示. 所示. 直至一趟排序结束后再将枢轴记录移至正确位置上.如算法 所示
wenku.baidu.com
3
例如, 展示了起泡排序的一个实例. 例如,图10.6展示了起泡排序的一个实例. 展示了起泡排序的一个实例 49 38 65 97 76 13 27 49 初 始 关 键 字 38 49 65 76 13 27 49 97 第 一 趟 排 序 后 38 49 65 13 27 49 76 第 二 趟 排 序 后 图10.6 38 49 13 27 49 65 38 13 27 49 49 13 27 38 49 13 27 38
5
起泡排序的效率: 起泡排序的效率: ①若初始序列为"正序"序列,则只需进行一趟排序,在排序过程中进行n-1 若初始序列为"正序"序列,则只需进行一趟排序,在排序过程中进行 次关键字间的比较,且不移动记录; 次关键字间的比较,且不移动记录; 2 若初始序列为"逆序"序列,则需要进行n-1趟排序 趟排序, ②若初始序列为"逆序"序列,则需要进行 趟排序,需进行 ∑ ( i 1) = n ( n 1) / 2 i=n 次比较,并作数量级的记录移动. 次比较,并作数量级的记录移动.
£10.7 各种内部排序方法的比较讨论
1
三,交换排序
基本原理: 基本原理:两两比较待排序的对象的关键 如果发生逆序,则交换之, 字,如果发生逆序,则交换之,直到全部 对象都排好序为止. 对象都排好序为止. 两种常见的交换排序
起泡排序(Bubble 起泡排序(Bubble Sort) 快速排序(Quick 快速排序(Quick Sort)
相关文档
最新文档