交换排序

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
while (i<j && r[i]<= r[j]) j--; //右侧扫描 if (i<j) {
r[i]=r[j]; i++; //将较小记录交换到前面 } while (i<j && r[i]<= r[j]) i++; //左侧扫描 if (i<j) {
r[j]=r[i]; j--; //将较大记录交换到后面 } } retutn i; //i为轴值记录的最终位置 }
比较次数:n-1 移动次数:0 时间复杂度为O(n)。
12 34 5 12 34 5
起泡排序算法的性能分析
最好情况(正序):
比较次数:n-1 移动次数:0
54 32 1
时间复杂度为O(n);
最坏情况(反序):
比较次数:n-1(n-i) = n (n -1)
i=1
2
移动次数:n-13(n-i)= 3n(n -1)
(2)i从前向后扫描,直到r[i]>r[j],将r[i]移动到r[j] 的位置,使关键字比基准大的记录移动到后面去;
(3)重复上述过程,直到i=j。
关键问题⑵:如何实现一次划分?
算法实现
int Partition(int r[ ], int l, int h) {
i=l; j=h; //初始化 while (i<j) {
较大记录从前面直接移动到后面 较小记录从后面直接移动到前面
快速排序的基本思想
首先选一个基准,通过一趟排序将待排序记录分割成 独立的两部分,前一部分记录的关键字均小于或等于
基准,后一部分记录的关键字均大于或等于基准,
然后分别对这两部分重复上述方法,直到整个序列有 序。
需解决的关键问题?
⑴如何选择基准? ⑵如何实现分割(称一次划分)? ⑶如何处理分割得到的两个待排序子序列? ⑷如何判别快速排序的结束?
关键问题⑶:如何处理分割得到的两个待排序子序列? 解决方法: 对分割得到的两个子序列递归地执行快速排序。
13
27
38
50
55
49
65
i
j
i
j
13
27来自百度文库
38
49
50
55
65
关键问题⑶:如何处理分割得到的两个待排序子序列?
算法实现
void QuickSort (int r[ ], int first, int end ) {
pos = Partition (r, first, end ); //一次划分 QuickSort (r, first, pos-1); //对前一个子序列进行快速排序 QuickSort (r, pos+1, end ); //对后一个子序列进行快速排序 }
关键问题⑷:如何判别快速排序的结束?
关键问题⑵:如何实现一次划分?
38
27 55
50
13 49
65
38
i
jjj
13
55 27
50
i
ii
49 65 j
13 27 38 50 55 49 65 ij j j
关键问题⑵:如何实现一次划分?
解决方法: 设待划分的序列是r[l] ~ r[h],设参数i,j分别指向子 序列左、右两端的下标l和h,令r[s]为轴值, (1)j从后向前扫描,直到r[j]<r[i],将r[j]移动到r[i] 的位置,使关键字比基准小的记录移动到前面去;
表与右侧子表的长度相同,为O(nlog2n)。
T(n)≤2T(n/2)+n ≤2(2T(n/4)+n/2)+n=4T(n/4)+2n ≤4(2T(n/8)+n/4)+2n=8T(n/8)+3n ……… ≤nT(1)+nlog2n=O(nlog2n)
快速排序的时间性能分析
最好情况 每一次划分对一个记录定位后,该记录的左侧
如何改变不对称性? 在排序过程中交替改变扫描方向——双向起泡排序
23 45 1 23 41 5
12 34 5
8.3.2 快速排序
改进的着眼点:在起泡排序中,记录的比较和移动是 在相邻单元中进行的,记录每次交换只能上移或下移 一个单元,因而总的比较次数和移动次数较多。
减少总的比较次数和移动次数
增大记录的比较和移动距离
关键问题⑴:如何选择基准?
选择基准的方法:
1.使用第一个记录的关键字; 2.选取序列中间记录的关键字; 3.比较序列中第一个记录、最后一个记录和中间 记录的关键码,取关键码居中的作为基准并调换 到第一个记录的位置; 4.随机选取基准。
选取不同基准的后果:
决定两个子序列的长度,子序列的长度最好相等。
快速排序是不稳定的。
if (first < end) { pos = Partition (r, first, end ); QuickSort (r, first, pos-1); QuickSort (r, pos+1, end );
} }
快速排序的时间性能分析
最好情况 每一次划分对一个记录定位后,该记录的左侧子
子表与右侧子表的长度相同,为O(nlog2n)。
最坏情况(正序或反序) 每次划分只得到一个比上一次划分少一个记录的
子序列(另一个子序列为空),为 O(n2)。
n -1
(n
- i )=
1
n(n
-1)
= O(n2 )
i =1
2
平均情况 :O(nlog2n)。
快速排序的空间性能分析
要用到栈 栈的大小:O(n) 如果每次都先处理较短的子序列,则栈的 大小为O(log2n)
交换排序
交换排序的主要操作是交换,其主要思想 是:在待排序列中选两个记录,将它们的关键 码相比较,如果反序(即排列顺序与排序后的 次序正好相反),则交换它们的存储位置。
反序则 交换
ri
rj
8.3.1起泡排序(相邻比较排序)
基本思想:两两比较相邻记录的关 键码,如果反序则交换,直到没有 反序的记录为止。
i=1
2
时间复杂度为O(n2)。
平均情况:时间复杂度为O(n2)。
如何再改进起泡排序?
1 2 3 4 5 需扫描1趟(轻泡浮上来) 5 4 3 2 1 需扫描n-1趟(轻泡浮上来) 5 1 2 3 4 需扫描2趟(重泡沉下去) 2 3 4 5 1 需扫描n-1趟(重泡沉下去)
造成不对称的原因是什么?
解决方法:
若待排序列中只有一个记录,显然已有序,否则进 行一次划分后,再分别对分割所得的两个子序列进 行快速排序(即递归处理)。
关键问题⑷:如何判别快速排序的结束?
算法实现
void QuickSort (int r[ ], int first, int end ) {//在序列 first~end中递归地进行快速排序
起泡排序过程示例
45 34 78 12 34’ 32 29 64
起泡排序算法的实现
(1) 如何判别起泡排序的结束? (2)在一趟起泡排序中,若有多个记录 位于最终位置,应如何记载? (3)如何确定起泡排序的范围,使得已 经位于最终位置的记录不参与下一趟排 序?
起泡排序算法的性能分析
最好情况(正序):
相关文档
最新文档