1 / 62
文档名称:

数据结构:内排序.pdf

格式:pdf   大小:789KB   页数:62
下载后只包含 1 个 PDF 格式的文档,没有任何的图纸或源代码,查看文件列表

如果您已付费下载过本站文档,您可以点这里二次下载

分享

预览

数据结构:内排序.pdf

上传人:窝窝爱蛋蛋 2023/1/3 文件大小:789 KB

下载得到文件列表

数据结构:内排序.pdf

相关文档

文档介绍

文档介绍:该【数据结构:内排序 】是由【窝窝爱蛋蛋】上传分享,文档一共【62】页,该文档可以免费在线阅读,需要了解更多关于【数据结构:内排序 】的内容,可以使用淘豆网的站内搜索功能,选择自己适合的文档,以下文字是截取该文章内的部分文字,如需要获得完整电子版,请下载此文档到您的设备,方便您编辑和打印。:.
数据结构:内排序
DataStructure
2016年3月15日星期二1:.
内排序
排序术语及记号
2
三种代价为O(n)的排序方法
shell排序
快速排序
归并排序
堆排序
分配排序和基数排序
对各种排序算法的实验比较
排序问题的下限
2016年3月15日星期二2:.
排序术语及记号
术语
记录——结点文件——线性表
关键码:能够唯一确定结点的一个或若干域。
排序码:作为排序运算依据的一个或若干域。
组合排序码,(主关键码,次关键码)
例,(总分数,数据结构分数,计算引论分数)
排序:排序就是将一组杂乱无章的数据按一定的
规律排列起来
2016年3月15日星期二3:.
术语
排序问题:给定一组记录r,r,...r,其排序码分别为
12n
k,k,…,k,将这些记录排成顺序为r,r,…,r的一
12ns1s2sn
个序列S,满足条件k≤k≤k。
s1s2sn
排序算法的稳定性:如果在对象序列中有两个对象r[i]和
r[j],它们的关键码k[i]==k[j],且在排序之前,对象
r[i]排在r[j]前面。如果在排序之后,对象r[i]仍在对象
r[j]的前面,则称这个排序方法是稳定的,否则称这个排
序方法是不稳定的。
排序——在内存中进行的排序
外排序——排序过程还要访问外存(因为待排记录的数量太
大,内存容纳不下)
2016年3月15日星期二4:.
插入排序
2016年3月15日星期二5:.
一趟直接插入排序的基本思想
有序序列A[1..i-1]无序序列A[i..n]
A[i]
有序序列A[1..i]无序序列A[i+1..n]
2016年3月15日星期二6:.
实现“一趟插入排序”分三步进行
[1..i-1]中查找A[i]的插入位置,
A[1..j].keyA[i].key<A[j+1..i-1].key;
[j+1..i-1]中的所有记录均后移
一个位置;
[i]插入(复制)到A[j+1]的位置上。
2016年3月15日星期二7:.
插入排序算法描述
template<typenameE,typenameComp>
voidinssort(EA[],intn){
for(inti=1;i<n;i++)
for(intj=i;(j>0)&&(Comp::prior(A[j],A[j-1]));j--)
swap(A,j,j-1);
}
2016年3月15日星期二8:.
加入监视哨的插入排序算法
template<typenameE,typenameComp>
voidinssort(EA[],intn){
for(inti=2;i<=n;i++)
{A[0]=A[i];j=i-1;
while(Comp::prior(x,A[j]))
{A[j+1]=A[j];j--;}
A[j+1]=A[0];
}
}
2016年3月15日星期二9:.
直接插入排序时间分析
最好的情况(关键字在记录序列中顺序有序):
“比较”的次数:“移动”的次数:
n
1n12(n-1)

i2
最坏的情况(关键字在记录序列中逆序有序):
“比较”的次数:“移动”的次数:
nn
nn(1)(n4)(n1)
(1)i(i1)
i22i22
2016年3月15日星期二10:.
冒泡排序
2016年3月15日星期二11:.
冒泡排序算法
template<typenameE,typenameComp>
voidbubsort(EA[],intn){
for(inti=0;i<n-1;i++)
for(intj=n-1;j>i;j--)
if(Comp::prior(A[j],A[j-1]))
swap(A,j,j-1);
}
2016年3月15日星期二12:.
改进的冒泡排序算法
template<typenameE,typenameComp>
voidbubsort(EA[],intn){
intflag;
for(inti=0;i<n-1;i++)
{flag=FALSE:
for(intj=n-1;j>i;j--)
if(Comp::prior(A[j],A[j-1]))
{swap(A,j,j-1);flag=TRUE;}
if(flag==FALSE)return;
}}
2016年3月15日星期二13:.
冒泡排序时间分析
最好的情况(关键字在记录序列中顺序有序):
只需进行一趟起泡
“比较”的次数:“移动”的次数:
n-10
最坏的情况(关键字在记录序列中逆序有序):
需进行n-1趟起泡
“比较”的次数:“移动”的次数:
22
n(n1)3n(n1)
(i1)3(i1)
in2in2
2016年3月15日星期二14:.
直接选择排序
2016年3月15日星期二15:.
直接选择排序算法
template<typenameE,typenameComp>
voidselsort(EA[],intn){
for(inti=0;i<n-1;i++){
intlowindex=i;//Rememberitsindex
for(intj=n-1;j>i;j--)//Findleast
if(Comp::prior(A[j],A[lowindex]))
lowindex=j;//Putitinplace
swap(A,i,lowindex);
}
}
2016年3月15日星期二16:.
直接选择排序时间性能分析
对n个记录进行简单选择排序,所需进
行的关键字间的比较次数总计为:
n1
n(n1)
(ni)
i12
移动记录的次数,最小值为0,最大值
为3(n-1)。
2016年3月15日星期二17:.
时间代价
InsertionBubbleSelection
Comparisons:
22
BestCase(n)(n)(n)
222
AverageCase(n)(n)(n)
222
WorstCase(n)(n)(n)
Swaps
BestCase00(n)
22
AverageCase(n)(n)(n)
22
WorstCase(n)(n)(n)
2016年3月15日星期二18:.
Shell排序

缩小增量排序法法(不稳定算法,时间代价O(n)
原理:n很小时,或基本有序时排序速度较快
2016年3月15日星期二19:.
希尔排序
将记录序列分成若干子序列,分别对每个子序列进
行插入排序。
例如:将n个记录分成d个子序列:
{A[1],A[1+d],A[1+2d],…,A[1+kd]}
{A[2],A[2+d],A[2+2d],…,A[2+kd]}

{A[d],A[2d],A[3d],…,A[kd],A[(k+1)d]}
其中,d称为增量,它的值在排序过程中从大到小逐
渐缩小,直至最后一趟排序减为1。
2016年3月15日星期二20:.
例如:
1625123047**********
第一趟希尔排序,设增量d=5
112312918162536304731
第二趟希尔排序,设增量d=3
918121123162531304736
第三趟希尔排序,设增量d=1
911121618232530313647
2016年3月15日星期二21:.
shell排序算法
template<typenameE,typenameComp>
voidinssort2(EA[],intn,intincr){
for(inti=incr;i<n;i+=incr)
for(intj=i;
(j>=incr)&&
(Comp::prior(A[j],A[j-incr]));j-=incr)
swap(A,j,j-incr);
}
2016年3月15日星期二22:.
shell排序算法
template<typenameE,typenameComp>
voidshellsort(EA[],intn){//Shellsort
for(inti=n/2;i>2;i/=2)//Foreachincr
for(intj=0;j<i;j++)//Sortsublists
inssort2<E,Comp>(&A[j],n-j,i);
inssort2<E,Comp>(A,n,1);
}
2016年3月15日星期二23:.
快速排序
2016年3月15日星期二24:.
快速排序
2016年3月15日星期二25:.
一趟快速排序
目标:找一个记录,以它的关键字作为
“枢轴”,凡其关键字小于枢轴的记录均
移动至该记录之前,反之,凡关键字大于
枢轴的记录均移动至该记录之后。
致使一趟排序之后,记录的无序序列A[s..t]
将分割成两部分:A[s..i-1]和A[i+1..t],且
A[j].key≤A[i].key≤A[j].key
(s≤j≤i-1)枢轴(i+1≤j≤t)。
2016年3月15日星期二26:.
例如A[0]
s52t
23145280
52498036145861972375
lowlowlowlowlowhighhighhighhighhighhigh
设A[s]=52为枢轴
将A[high].key和枢轴的关键字进行比较,
要求A[high].key≥枢轴的关键字
将A[low].key和枢轴的关键字进行比较,
要求A[low].key≤枢轴的关键字
2016年3月15日星期二27:.
快速排序
首先对无序的记录序列进行“一次划分”,之
后分别对分割所得两个子序列“递归”进行快速
排序。
无序的记录序列
一次划分
枢轴无序子序列(2)
无序记录子序列(1)
分别进行快速排序
2016年3月15日星期二28:.
快速排序算法
template<typenameE,typenameComp>
voidqsort(EA[],inti,intj){
if(j<=i)return;//Listtoosmall
intpivotindex=findpivot(A,i,j);
swap(A,pivotindex,j);//Putpivotatend
//kwillbefirstpositiononrightside
intk=partition<E,Comp>(A,i-1,j,A[j]);
swap(A,k,j);//Putpivotinplace
qsort<E,Comp>(A,i,k-1);
qsort<E,Comp>(A,k+1,j);
}
2016年3月15日星期二29:.
快速排序算法
template<typenameE>
inlineintfindpivot(EA[],inti,intj)
{return(i+j)/2;}
template<typenameE,typenameComp>
inlineintpartition(EA[],intl,intr,E&pivot){
do{//Movetheboundsinuntiltheymeet
while(Comp::prior(A[++l],pivot));
while((l<r)&&Comp::prior(pivot,A[--r]));
swap(A,l,r);//Swapout-of-placevalues
}while(l<r);//Stopwhentheycross
swap(A,l,r);//Reverselastswap
returnl;//Returnfirstposonright
}
2016年3月15日星期二30
:.
快速排序的时间分析
假设一次划分所得枢轴位置i=k,则对n个记录进
行快排所需时间:
T(n)=T(n)+T(k-1)+T(n-k)
pass
其中T(n)为对n个记录进行一次划分所需时间。
pass
若待排序列中记录的关键字是随机分布的,则k取
1至n中任意一值的可能性相同。
2016年3月15日星期二31:.
由此可得快速排序所需时间的平均值为:
n
1
T(n)CnT(k1)T(nk)
avgavgavg
nk1
设T(1)≤b
avg
则可得结果:
b
Tavg(n)(2c)(n1)ln(n1)
2
结论:快速排序的时间复杂度为O(nlogn)
2016年3月15日星期二32:.
快速排序的时间分析
若待排记录的初始状态为按关键字有序
时,快速排序将蜕化为起泡排序,其时间
2
复杂度为O(n)。
2016年3月15日星期二33:.
归并排序
通常采用的是2-路归并排序。即:将两个
位置相邻的记录有序子序列
有序子序列R[l..m]有序子序列R[m+1..n]
归并为一个记录的有序序列。
有序序列R[l..n]
2016年3月15日星期二34:.
归并排序
Listmergesort(Listinlist){
if(()<=1)returninlist;
Listl1=halfoftheitemsfrominlist;
Listl2=otherhalfofitemsfrominlist;
returnmerge(mergesort(l1),mergesort(l2));
}
2016年3月15日星期二35:.
归并排序的算法
如果记录无序序列A[left..right]的两部分
A[left..(left+right)/2]和A[(left+right)/2+1..right]
分别按关键字有序,
则利用上述归并算法很容易将它们归
并成整个记录序列是一个有序序列。
由此,应该先分别对这两部分进行
2-路归并排序。
2016年3月15日星期二36:.
例如:
52,23,80,36,68,14(left=1,right=6)
[52,23,80][36,68,14]
[52,23][80][36,68][14]
[52][23][36][68]
[23,52][36,68]
[23,52,80][14,36,68]
[14,23,36,52,68,80]
2016年3月15日星期二37:.
归并排序算法
template<typenameE,typenameComp>
voidmergesort(EA[],Etemp[],intleft,intright){
if(left==right)return;
intmid=(left+right)/2;
mergesort<E,Comp>(A,temp,left,mid);
mergesort<E,Comp>(A,temp,mid+1,right);
for(inti=left;i<=right;i++)//Copy
temp[i]=A[i];
inti1=left;inti2=mid+1;
for(intcurr=left;curr<=right;curr++){
if(i1==mid+1)//Leftexhausted
A[curr]=temp[i2++];
elseif(i2>right)//Rightexhausted
A[curr]=temp[i1++];
elseif(Comp::prior(temp[i1],temp[i2]))
A[curr]=temp[i1++];
elseA[curr]=temp[i2++];
2016年}}3月15日星期二38
:.
优化归并排序算法
template<typenameE,typenameComp>
voidmergesort(EA[],Etemp[],intleft,intright){
if((right-left)<=THRESHOLD){
inssort<E,Comp>(&A[left],right-left+1);
return;
}
inti,j,k,mid=(left+right)/2;
if(left==right)return;
mergesort<E,Comp>(A,temp,left,mid);
mergesort<E,Comp>(A,temp,mid+1,right);
for(i=mid;i>=left;i--)temp[i]=A[i];
for(j=1;j<=right-mid;j++)
temp[right-j+1]=A[j+mid];
for(i=left,j=right,k=left;k<=right;k++)
if(temp[i]<temp[j])A[k]=temp[i++];
elseA[k]=temp[j--];
}
2016年3月15日星期二39
:.
归并排序算法效率
设需排序元素的数目为n,递归的深度为logn
(简单起见,设n是2的幂),第一层递归是对一
个长度为n的数组排序,下一层是对两个长度为
n/2的子数组排序,…,最后一层对n个长度为1
的子数组排序。
时间复杂度:T(n)=O(nlog2n)
空间复杂度:S(n)=O(n)
2016年3月15日星期二40:.
堆排序
堆排序:
将无序序列建成一个堆,得到关键字最小(或最
大)的记录;输出堆顶的最小(大)值后,使剩
余的n-1个元素重又建成一个堆,则可得到n个元
素的次小值;重复执行,得到一个有序序列,这
个过程叫堆排序。
堆排序需解决的两个问题:
如何由一个无序序列建成一个堆?
如何在输出堆顶元素之后,调整剩余元素,使之
成为一个新的堆?
2016年3月15日星期二41
:.
建堆是一个从下往上进行“筛选”的过程
例如:排序之前的关键字序列为
4098
5581499849
73817312363627984940
81735564361212
现在,左/右子树都已经调整为堆,最后只要调
整根结点,使整个二叉树是个“堆”即可。
2016年3月15日星期二42:.
堆排序算法
第二个问题解决方法——筛选
输出堆顶元素之后,以堆中最后一个元素替代之;然后将根
结点值与左、右子树的根结点值进行比较,并与其中小者进
行交换;重复上述操作,直至叶子结点,将得到新的堆,称
这个从堆顶至叶子的调整过程为“筛选”。
堆排序算法
template<typenameE,typenameComp>
voidheapsort(EA[],intn){//Heapsort
Emaxval;
maxheap<E,Comp>H(A,n,n);
for(inti=0;i<n;i++)//Nowsort
maxval=();//Putmaxatend
}
2016年3月15日星期二43
:.
HeapsortExample(1)
2016年3月15日星期二44:.
HeapsortExample(2)
2016年3月15日星期二45:.
堆排序的时间复杂度分析
,“筛选”所需进行的关键字
比较的次数至多为2(k-1);
,建成深度为h(=logn+1)的堆,
2
所需进行的关键字比较的次数至多4n;
“堆顶”n-1次,总共进行的关键
字比较的次数不超过
2(log(n-1)+log(n-2)+…+log2)<2n(logn)
2222
因此,堆排序的时间复杂度为O(nlogn)。
2016年3月15日星期二46:.
分配排序和基数排序
Asimple,efficientsort:
for(i=0;i<n;i++)
B[A[i]]=A[i];
Waystogeneralize:
Makeeachbintheheadofalist.
Allowmorekeysthanrecords.
2016年3月15日星期二47:.
分配排序
template<typenameE,classgetKey>
voidbinsort(EA[],intn){
List<E>B[MaxKeyValue];
Eitem;
for(i=0;i<n;i++)B[A[i]].append(getKey::key(A[i]));
for(i=0;i<MaxKeyValue;i++)
for(B[i].setStart();
B[i].getValue(item);B[i].next())
output(item);
}
2016年3月15日星期二48:.
基数排序
2016年3月15日星期二49:.
SupposethattherecordRhasrkeys.
i
j
K::=thej-thkeyofrecordR
ii
0
K::=themostsignificantkeyofrecordR
ii
r1
K::=theleastsignificantkeyofrecordR
ii
AlistofrecordsR,...,Rislexicallysortedwithrespect
0n1
01r1
totheke

最近更新

2025湖南省演出公司公开招聘2人备考题库附答案.. 42页

2025重庆成飞新材料股份公司招聘3人考试题库附.. 46页

2026国家交通运输部所属事业单位第三批招聘19.. 45页

2026年c语言上机考试题库完整参考答案 13页

2026年c语言期末考试题库(a卷) 13页

2026年C语言程序设计理论试题库(夺冠系列) 13页

2026年c语言试题期末及完整答案一套 13页

2024年东宁县招教考试备考题库完美版 33页

2026年中国城市建设史复习题100道含答案(突破.. 44页

2024年宁阳县选聘县直事业单位工作人员历年真.. 66页

2024年徽商职业学院辅导员招聘考试真题汇编附.. 35页

2024年沂源县选聘县直事业单位工作人员历年真.. 67页

2024年漯河食品工程职业大学辅导员考试参考题.. 36页

2026年卧底笔试题库100道含答案(轻巧夺冠) 39页

2026年吉林省吉林市单招职业适应性考试题库附.. 45页

2025年新疆铁道职业技术学院单招职业技能考试.. 45页

2025年河北张家口康保县二人台艺术团第二次公.. 38页

2025广东汕头大学招聘事业单位人员5人考试备考.. 48页

2025广西河池市那桃乡招聘村级防返贫监测信息.. 36页

2025江苏省环保集团有限公司本部信息化数字化.. 48页

2025浙江嘉兴职业技术学院招聘高层次人才28人.. 50页

2026年山西信息职业技术学院单招职业适应性测.. 44页

2025重庆万盛经开区创业就业和人才中心公益岗.. 35页

2026年平顶山文化艺术职业学院单招职业技能考.. 43页

2026中国能源建设集团云南省电力设计院有限公.. 44页

2025交通运输部所属事业单位第七批统一招聘10.. 18页

2026年江西交通职业技术学院单招职业倾向性考.. 37页

2025年新疆考试录用公务员《公安专业科目》真.. 30页

2024年南京信息职业技术学院单招职业技能测试.. 78页

CFG群桩基础土方开挖施工方案 6页