交换类排序
来源:互联网 发布:淘宝网第三方平台 编辑:程序博客网 时间:2024/06/05 10:43
交换排序主要是根据记录的关键字的大小,将记录交换来进行排序的。交换排序的特点是:将关键字值较大的记录向序列的后部移动,关键字较小的记录向前移动。这里介绍两种交换排序方法,它们是冒泡排序和快速排序。
冒泡排序
将被排序的记录数组R[1..n]垂直排列,每个记录R[i]看作是重量为R[i].key的气泡。根据轻气泡不能在重气泡之下的原则,从下往上扫描数组R:凡扫描到违反本原则的轻气泡,就使其向上"飘浮"。如此反复进行,直到最后任何两个气泡都是轻者在上,重者在下为止。
1.算法思路
(1)让j取n至2,将r[j].key与r[j-1].key比较,如果r[j].key<r[j-1].key,则把记录r[j]与r[j-1]交换位置,否则不进行交换。最后是r[2].key与r[1].key对比,关键字较小的记录就换到r[1]的位置上,到此第一趟结束。最小关键字的记录就象最轻的气泡冒到顶部一样换到了文件的前边。
(2)让j取n至3,重复上述的比较对换操作,最终r[2]之中存放的是剩余n-1个记录(r[1]除外)中关键字最小的记录。
(3) 让j取n至i+1,经过一系列对联对比交换之后,r[i]之中是剩余若干记录中关键字最小的记录。
(4) 让j取n至n-1,将r[n].key与r[n-1].key对比,把关键字较小的记录交换到r[n-1]之中。
【例】 设有一组关键字序列{ 55 , 22 , 44 , 11 , 33 },这里 n=5 ,即有 5 个记录。请将其按由小到大的顺序排序。 如图9.3
具体算法演示请点击查看【算法演示】
2.具体算法
/*冒泡排序,时间复杂度为o(n2),稳定排序,适合规模比较小的*/
for(i=0; i<n; i++) { for(j=i+1; j<n; j++) { if(arr[i] < arr[j]) { int temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; } } }
void bubble_sort(int array[],int n){ int i,j,flag,temp; for(i = 0; i < n-1; i++) { for(j = 0; j < n-i-1; j++) { if(array[j] > array[j+1]) { temp = array[j]; array[j] = array[j+1]; array[j+1] = temp; } }}
该算法的时间复杂度为O(n2)。但是,当原始关键字序列已有序时,只进行一趟比较就结束,此时时间复杂度为O(n)。
1、算法思想
(1) 分治法的基本思想
(2)快速排序的基本思想
①分解:
②求解:
③组合:
2、快速排序算法QuickSort
void QuickSort(SeqList R,int low,int high) { //对R[low..high]快速排序 int pivotpos; //划分后的基准记录的位置 if(low<high){//仅当区间长度大于1时才须排序 pivotpos=Partition(R,low,high); //对R[low..high]做划分 QuickSort(R,low,pivotpos-1); //对左区间递归排序 QuickSort(R,pivotpos+1,high); //对右区间递归排序 } } //QuickSort
(1)简单的划分方法
① 具体做法
第一步:(初始化)设置两个指针i和j,它们的初值分别为区间的下界和上界,即i=low,j=high;选取无序区的第一个记录R[i](即R[low])作为基准记录,并将它保存在变量pivot中;
第二步:令j自high起向左扫描,直到找到第1个关键字小于pivot.key的记录R[j],将R[j])移至i所指的位置上,这相当于R[j]和基准R[i](即pivot)进行了交换,使关键字小于基准关键字pivot.key的记录移到了基准的左边,交换后R[j]中相当于是pivot;然后,令i指针自i+1位置开始向右扫描,直至找到第1个关键字大于pivot.key的记录R[i],将R[i]移到i所指的位置上,这相当于交换了R[i]和基准R[j],使关键字大于基准关键字的记录移到了基准的右边,交换后R[i]中又相当于存放了pivot;接着令指针j自位置j-1开始向左扫描,如此交替改变扫描方向,从两端各自往中间靠拢,直至i=j时,i便是基准pivot最终的位置,将pivot放在此位置上就完成了一次划分。
②一次划分过程
初始关键字 [49 38 65 97 76 13 27 49]
第一次交换后 [27 38 65 97 76 13 49 49]
第二次交换后[27 38 49 97 76 13 65 49]
J向左扫描,位置不变,第三次交换后 [27 38 13 97 76 49 65 49]
I向右扫描,位置不变,第四次交换后 [27 38 13 49 76 97 65 49]
J向左扫描 [27 38 13 49 76 97 65 49]
(一次划分过程)
③划分算法:
int Partition(SeqList R,int i,int j) {//调用Partition(R,low,high)时,对R[low..high]做划分, //并返回基准记录的位置 ReceType pivot=R[i]; //用区间的第1个记录作为基准 ' while(i<j){ //从区间两端交替向中间扫描,直至i=j为止 while(i<j&&R[j].key>=pivot.key) //pivot相当于在位置i上 j--; //从右向左扫描,查找第1个关键字小于pivot.key的记录R[j] if(i<j) //表示找到的R[j]的关键字<pivot.key R[i++]=R[j]; //相当于交换R[i]和R[j],交换后i指针加1 while(i<j&&R[i].key<=pivot.key) //pivot相当于在位置j上 i++; //从左向右扫描,查找第1个关键字大于pivot.key的记录R[i] if(i<j) //表示找到了R[i],使R[i].key>pivot.key R[j--]=R[i]; //相当于交换R[i]和R[j],交换后j指针减1 } //endwhile R[i]=pivot; //基准记录已被最后定位 return i; } //partition
4、算法分析
(1)最坏时间复杂度
(2) 最好时间复杂度
注意:
(3)基准关键字的选取
①"三者取中"的规则
②取位于low和high之间的随机数k(low≤k≤high),用R[k]作为基准
注意:
(4)平均时间复杂度
(5)空间复杂度
(6)稳定性
- 排序---交换类排序
- 交换类排序
- 数据结构-交换类排序
- 交换类排序
- 交换类------冒泡排序
- 交换类排序
- 2.排序-交换类排序
- 交换类排序-快速排序
- 内部排序-交换类排序
- 内排序-交换类排序-冒泡排序
- 内排序-交换类排序-快速排序
- 排序-交换类排序-快速排序、归并排序、冒泡排序
- 深入浅出交换类排序算法
- 深入浅出交换类排序算法
- 数据结构-排序之交换类排序
- 数据结构之排序--交换类排序
- 交换类排序——冒泡排序
- 交换类排序之快速排序
- Const用法小结
- Meta详细说明及使用方法-seo页面关键字设置
- Visual Stadio对于不返回任何键列信息的 SelectCommand,不支持 UpdateCommand 的动态 SQL 生成
- flash builder 4.5.1 手机开发调用WEBSERVICE注意事项
- Android中使用PULL方式解析XML文件
- 交换类排序
- java爬虫代理
- 梦
- zombie process and orphan process
- codeforces #80div2 C【无向图判单环】
- 使用HttpURLConnection上传文件
- C#输出的XML文件中空标签多换行符
- oracle 11g 环境变量设置
- u-boot-2011.06在基于s3c2440开发板的移植之解决raise: Signal # 8 caught