折半插入排序算法voidBinSortSqListL.PPT

折半插入排序算法voidBinSortSqListL

第9章 排序 排序(Sorting)是数据处理领域中一种最重要运算。简单地说,排序就是将一个数据对象调整为具有某种顺序的序列的操作。 本章要点 排序的基本概念 各种内部排序算法及算法分析 各种内部排序算法的比较 章节安排 9.1排序概述 9.2插入排序 9.3交换排序 9.4选择排序 *9.5归并排序 *9.6基数排序 9.7各种内部排序方法的比较 9.1 排序概述 假设一个数据对象所包含的n个记录(或数据元素)为{R1,R2,…,Rn}其相应的关键字序列为{K1,K2,…,Kn} 然后依据关键字序列确定n个 记录的一种排列p1,p2,…,pn,使得关键字满 足Kp1≤Kp2≤…≤Kpn或 Kp1≥Kp2≥…≥Kpn , 使{R1,R2,…,Rn}的n个记录成为一个按关键 字有序的序列{Rp1,Rp2,…,Rpn } 这样一种 操作称为排序。 本章中设待排序的记录以数组形式存放,待排序记录个数用 n表示,关键字均为整数,待排序表的数据类型定义如下: #define MAXSIZE 20 /*待排序记录的个数*/ typedef int KeyType; /*关键字为整数*/ typedef struct{ KeyType key; /*关键字域*/ DataType otherdata; /*其他数据域,算法中不必考虑*/ }RList; /*待排序的记录类型*/ typedef struct{ RList r[MAXSIZE+1]; /*待排序数据,其中r[0]作为哨兵或辅助单元或闲置*/ int length; /*待排序记录个数*/ }SqList; /*待排序表的类型*/ 9.2.1 直接插入排序 直接插入排序是最简单的排序方法之一。它的基本思想是:将一个待排序的记录插入到一个已排好序的有序表,得到一个记录个数增1的新的有序表。 【算法9.1】直接插入排序算法 void InsertSort(SqList L) { int i,j; for(i=2;i=L.length;i++){ L.r[0]=L.r[i]; /*设置哨兵*/ j=i-1; /*设置查找开始位置*/ while(L.r[0].key L.r[j].key){ L.r[j+1]= L.r[j]; /*记录后移*/ j--; /*继续查找插入位置*/ } L.r[j+1]= L.r[0]; /*完成一次插入*/}} 算法性能分析: 在最好情况下,所需要的比较次数为n-1次,移动次数为2(n-1)次,排序的时间复杂度为O(n)。在最坏情况下,所需要的比较次数为(n2+n+1)/2,移动次数为,排序的时间复杂度为O(n2)。 例9.1设有一组关键字序列为(25,24,69,25*,21,15),试按非递减的次序排序。其直接插入排序过程如图9.1所示。 9.2.2 折半插入排序 折半插入排序的基本思想:与直接插入排序相近,只是L.r[0].key总是与有序表的中间记录进行比较,若比中间记录小,则插入到中间记录的前面区域,否则插入到中间记录的后面区域;重复这些操作直到插入区域的左边界大于右边界,则左边界就是应插入的位置。 【算法9.2】折半插入排序算法 void BinSort(SqList L) { int i,low,high,mid; /*low:左边界,high:右边界,mid:中间位置*/ for(i=2;i=L.length;i++){ L.r[0]=L.r[i]; /*设置哨兵*/ Low=1;high=i-1; /*设置左右边界的初值*/ (续) while(low=high){ /*查找条件是左边界小于或等于右边界*/ mid=(low+high)/2; /*求中间位置*/ if(L.r[0].keyL.r[mid].key) high=mid-1; /*在中间位置的前面,修改右边界*/ else low=mid+1; /*/*在中间位置的后面,修改左边界*/ } for(j=i-1;j=low;j--) L.r[j+1]=L.r[j]; /*记录后移*/ L.r[low]= L.r[0]; /*完成一次插入*/ } } 算法性能分析:从时间效率看,比较次 数时间复杂度为O(nlog2n),与直接插入 排序相比,比较次数有所减少,但移动 次数一样,所以总的时

文档评论(0)

1亿VIP精品文档

相关文档