算法设计与分析电子教案.docx
《算法设计与分析电子教案.docx》由会员分享,可在线阅读,更多相关《算法设计与分析电子教案.docx(108页珍藏版)》请在冰豆网上搜索。
算法设计与分析电子教案
算法分析与设计教案
刘淑英
第一章基础
第二章分治与递归
第三章贪心法
第四章动态规划
第五章检索与周游
第六章回溯法
第七章分枝限界法
教学目的:
使学生了解课程的性质和任务,掌握集合的表示方法与操作算法。
教学重点:
使学生初步认识课程的性质与作用,激发课程学习热情。
教学难点:
理解集合表示的数据结构,掌握集合的操作算法设计。
1.1课程简介
1.2算法介绍
一、抽象问题类型
工程实例简介:
1)邮路问题;2)库存问题。
抽象化:
1)旅行商问题(TSP:
travelingsalesmanproblems)
n个城市,已知任意两个城市之间的距离。
从某个城市出发,经过余下的n-1个城市各一次,最后返回该城市,求所有可行路径[总共(n-1)!
条]中距离最短的一条路径。
2)0/1背包问题(knapsackproblems)
二、基本解题算法
穷举法,当不考虑约束条件时,可行解的总数
1)
2)O(2n)
可见,可行解的总数按指数规律增长。
三、课程任务
1)学习求解特定问题类型的有效算法(非数值计算问题)
抽象问题类型:
等价类问题,检索与周游,分类问题,最优化问题(背包问题,TSP问题,调度问题等),组合问题(n-皇后问题,子集和数问题,图着色问题等)。
算法设计方法:
分治法,贪心法,动态规划,回溯法,分支限界法,并行算法,递归与消除递归。
2)学习算法的表示方法
3)学习怎样分析算法的正确性
4)基本学会分析算法的效率
四、教学形式
讲授:
经典算法设计方法,针对抽象问题类的典型算法实例;
课外设计与上机:
编程上机实现经典问题的解题算法。
五、主要学习方法
课前预习,课堂听课与讨论,课后复习,大量的课外设计与上机编程实现。
六、考核方式
考查:
综合评价课堂学习态度、课堂讨论或回答问题的正确性、课外设计与上机、期末算法设计与编程联机考试等环节(公开题库,采用程序设计大赛形式)。
七、课程重要性
八、主要参考资料
[1]王晓东,算法设计与分析,北京:
清华大学出版社,2003.
[2]ThomasH.Cormen,CharlesE.Leiserson,RonaldL.Rivest,CliffordStein,算法导论,第二版影印版,北京:
高等教育出版社.
[3]严蔚敏,吴伟民,数据结构(C语言版),北京:
[4]BaaseS.andCelderA.V.,ComputerAlgorithm:
IntroductiontoDesignandAnalysis,thethirdedition,AddisonWesleyLongman,2000.
[5]HorowitzE.andSahniS.,FundamentalsofComputerAlgorithms,ComputerSciencePress,PitmanInc,1978.
[6]ShafferC.A.,DataStructureandAlgorithmAnalysis,Prentice-HallInc,中译本:
《数据结构与算法分析》,张铭、刘晓丹,电子工业出版社,1998.
[7]SartajShani,DataStructures,Algorithms,andApplicationsinC++,Prentice-HallInc,Homepage:
[8]KnuthD.E.著,管纪文译,《计算机程序设计技巧》,国防工业出版社,第一卷,1978,第二卷,1982.
[9]郭观七,甘靖,算法设计与分析实验指导书,自编,2006.
1.3集合的表示方法与操作算法
一问题
n个元素的集合U,可构造出许多互不相交的子集.例如
U={1,2,3,4,5,6,7,8,9,10},S1={1,7,8,9},S2={2,5,10},S3={3,4,6}
如何实现查找与并运算?
二集合的表示
1.位向量表示法
typedefstruct{typedefunion{
unsignedbit1:
1;struct{unsignedbit1:
1;
unsignedbit2:
1;unsignedbit2:
……
unsignedbitn:
1;unsignedbitn:
1;}bits;
}SET;unsignedword[
];
}SET;
biti=
查找,并,交运算方法;
计算复杂性说明.
2.树结构表示法
用树结构表示的集合
集合的合并操作示意图
描述:
typedefstruct{
ElemTypedata;
inttag;/*根节点的值为负数,其它节点为指向父节点的指针*/
}ELEM;
ELEMset[n];/*初始化时每个集合元素与数组下标建立一对一映射关系*/
3.树结构表示法下集合操作算法
并操作:
voidU(inti,intj)
{
set[i].tag=j;
}
查找操作:
intF(inti)
{intj=i;
while(set[j].tag>=0)j=set[j].tag;
returnj;
n-1次并运算生成的退化树
计算复杂性分析:
并运算可能产生退化树;
并运算的计算复杂性为O
(1);
查找的计算复杂性可达O(n).
4.改进的操作算法
带加权规则的并操作:
如果集合i的元素少于集合j的元素,集合i合并到集合j,否则集合j合并到集合i.
实现方法:
根节点的tag域表示该集合的基数的负值,合并时根据集合的基数大小将小的集合合并到大的集合中,其算法为
voidunion(inti,intj)
{intsum=set[i].tag+set[j].tag;
if(set[i].tag>set[j].tag){set[i].tag=j;set[j].tag=sum;}
else{set[j].tag=i;set[i].tag=sum;}
利用加权规则得到的树
关于集合树的最大深度
引理1.3设T是一颗由算法union所产生的有n个节点的树,在T中没有节点的级数会大于
.
使用加权规则并运算产生的一棵最坏情况树
使用带加权操作的并运算后,并运算的计算复杂性为O
(1),查找算法的计算复杂性为O(logn).
压缩规则:
如果j是由i到它的根节点的路径上的一个节点,则置parent(j)=root(i), 带压缩规则的查找算法为:
intfind(inti)
{intt,j=i;while(set[j].tag>=0)j=set[j].tag;/*searchroot*/
while(i!
=j){t=set[i].tag;set[i].tag=j;i=t;}/*shorteningpath*/
m次查找和n-1次并运算的计算复杂性:
引理1.3设T(m,n)是处理m≥n次find和n-1次union的混合序列所要求的最坏情况时间,则对于某两个正常数k1和k2有
实际上无论m,n增长多快,union-find的时间复杂度几乎与find的次数m成线性关系.
1.4小结
一个重点:
认识本课程的实用价值;
一个难点:
掌握集合的树结构表示和操作算法.
作业:
思考题:
p34.5~p34.9
掌握应用递归实现分治的算法设计思想,基本掌握将递归算法改写成迭代算法的方法。
分治法和递归的问题求解思想,针对问题的经典分治算法。
将递归算法改写成迭代算法的一般方法。
2.1基本策略
一、求解大规模问题的复杂性
当问题的输入规模很大,直接求解非常困难,甚至不可能。
二、分治策略-化整为零、分别求解
将输入规模为n(n值很大)的问题,分解成k(1<k≤n=个与原问题有相同类型的子问题,分别求解k个子问题,将k个子问题的解以适当方式合并成原问题的解。
三、抽象的分治算法
设原问题的输入用外部数组a[n]表示,简记为(1,n);
子问题对应输入数据a[p]~a[q],简记为(p,q).
已知:
SOLUTION为表示问题的解的抽象数据类型;
intdivide(int,int);/*将问题进行分解的函数*/
intsmall(int,int);/*判断最小子问题的布尔函数*/
SOLUTIONconquer(int,int);/*求解最小子问题的函数*/
SOLUTIONcombine(SOLUTION,SOLUTION);/*合并子问题的解*/
抽象的分治算法可用下面的递归过程描述:
SOLUTIONDandC(p,q)/*divideandconquer*/
{if(small(p,q))returnconquer(p,q);
else{
m=divide(p,q);
returncombine(DandC(p,m),DandC(m+1,q));
对原问题求解,通过调用DandC(1,n)实现。
2.2二分检索
一、问题
n个按非降次序排列的元素a[n],查找元素x是否在表中出现,若找到,返回其下标值,否则,返回一负数.
原问题可表示为:
I=(n,a[0],…,a[n-1],x)
二、分治的基本思路
数据分组:
a[0]~a[k-2];
a[k-1];
a[k]~a[n-1].
对应于三个子问题:
I1=(k-1,a[0],…,a[k-2],x);
I2=(1,a[k-1],x);
I3=(n-k,a[k],…,a[n-1],x).
三、递归算法
设a[n]为外部数组,二分检索的递归算法可描述为
intBinSearch1(p,q,x)
{intk=(p+q)/2;
if(q
if(x==a[k])returnk;
if(xif(x>a[k])returnBinSearch(k+1,q,x);}四、迭代算法设a[n]为外部数组,二分检索的递归算法可描述为intBinSearch2(n,x){intl=0,h=n-1,k;while(l<=h){k=(l+h)/2;if(xelseif(x>a[k])l=k+1;elsereturnk;}return–1;} 五、计算复杂度分析1.二元比较树以有序表的中间元素为根节点的二分树,左子树上所有元素不比父节点元素值大,右子树上所有元素不比父节点元素值小.例如,由元素1,2,3,4,5,6,7,8,9构成的有序表,对应的二元比较树内节点,外节点------成功检索,不成功检索二分检索树的深度k=二元比较树的深度k=2.时间复杂度定理2.2若n在区域[2k-1,2k)中,则对于一次成功的检索,BinSearch至多作k次比较;而对于一次不成功的检索,或者作k-1次比较或者作k次比较。成功检索最好情况:O(1)不成功检索最好情况:O(k)=O()=O(logn)成功检索最坏情况:O(k)=O()=O(logn)不成功检索最坏情况:O(k)=O()=O(logn)平均情况分析:内部路径长度之和I,外部路径长度之和E,E=I+2n。成功检索的平均比较次数:S(n)=(I/n)+1不成功检索的平均比较次数:U(n)=E/(n+1)显然,S(n)=(1+1/n)U(n)-1,因为U(n)为O(logn),所以S(n)也为O(logn)。成功检索不成功检索最好最坏平均最好最坏平均O(1)O(logn)O(logn)O(logn)O(logn)O(logn)3.以比较为基础检索的时间下界定理2.3设a[n]含有n(n≥1)个不同元素,排序为a[1]<….由此可见,任何以比较为基础的检索算法,最坏情况下的比较次数都不可能低于O(logn),因此,二分检索是最优的最坏情况算法.2.3找最大和最小元素一、问题在含有n个不同元素的集合a[n]中同时找出它的最大和最小元素.二、直接算法StraitSearch(n,&max,&min){*max=*min=a[0];for(i=1;i{if(a[i]>max)max=a[i];if(a[i]}}比较次数2(n-1),若将语句1改写成if(a[i]>max)max=a[i];elseif(a[i]最好情况n-1,最坏情况2(n-1),平均情况3/2(n-1).三、实现分治策略的递归算法●集合只有一个元素时max=min=a[i]●集合只有两个元素时if(a[i]else{max=a[i];min=a[j];}●集合中有更多元素时将原集合分解成两个子集,分别求两个子集的最大和最小元素,再合并结果.●数据类型typedefstruct{ElemTypemax,min;}SOLUTION;●算法SOLUTIONMaxMin(i,j){SOLUTIONs,s1,s2;if(i==j){s.max=s.min=a[i];returns;}/*一元素*/if(i==j-1)/*两元素*/{if(a[i]else{s.max=a[i];s.min=a[j];}returns;}k=(i+j)/2;s1=MaxMin(i,k);s2=MaxMin(k+1,j);/*多元素时分治*/(s1.max>=s2.max)?(s.max=s1.max):(s.max=s2.max);/*解的合并*/(s1.min<=s2.min)?(s.min=s1.min):(s.min=s2.min);returns;}●时间复杂度令t(n)表示MaxMin需要的元素比较次数,存在下列递推关系当n是2的幂时,即对于某个正整数k,n=2k,有t(n)=2t(n/2)+2=2(2t(n/4)+2)+2=4t(n/4)+4+2=2k-1t(2)+=2k-1+2k-2=3n/2-2注意:当n是2的幂时,3n/2-2是最好、最坏及平均情况下的比较次数,与直接算法的最坏情况相比,少25%.当元素的比较开销与整数比较开销相当时,将MaxMin的前两条if语句合并为:if(i>=j-1)/*对应一元素和两元素的情况*/{if(a[i]else{s.max=a[i];s.min=a[j];}returns;}MaxMin需要的比较次数,存在下列递推关系比StraitSearch算法的3(n-1)低.但MaxMin需要更多存储空间和更多的堆栈操作,实际效率可能更低。四、结论当元素的比较开销比整数比较开销大得多时,MaxMin算法比StraitSearch算法效率高,反之,效率低.因此,分治策略只能看成是一个较好的但并不总是真正好的设计策略。思考题:1.请分析和证明E=I+2n。2.请分析c(n)递推关系式中常数3为什么是3而不是2?2.4分类一、问题给定一个含n个元素的集合a[n],按一定次序(本课程假定均为非降次序)将其分类(排序).二、插入分类●原理已分类的部分未分类的部分a[1]…a[j-1]a[j]a[j+1]…a[n]将未分类的元素逐个插入到已分类部分的正确位置上.●插入分类算法InsertSort(intn){for(j=1;j{for(unsorted=a[j],k=j-1;(k>=0)&&(unsorteda[k+1]=a[k];a[k+1]=unsorted;}}●时间复杂度考虑内层for循环中元素比较的次数T(n):最坏情况T(n)==1+2+…n-1==O(n2)最好情况T(n)=O(n) 三、归并分类●原理a[low]…a[]a[]…a[high]归并分类归并分类按非降次序合并两个已分类的子集●归并分类的递归算法MergeSort(low,high){if(low{mid=(low+high)/2;MergeSort(low,mid);MergeSort(mid+1,high);Merge(low,mid,high);}}●已分类子集的归并过程示例A1345691027811121314指针L=1,K=1,H=8B1指针L=2,H=8,K=2B12指针L=2,H=9,K=3B123456指针L=5,H=9,K=7B12345678指针L=5,H=11,K=9B12345678910指针L=8,H=11,K=11B1234567891011121314指针L=8,H=15,K=15Merge(low,mid,high){ElemTypeb[n];l=low;h=mid+1;k=l;while((l<=mid)&&(h<=high))/*部分合并*/{if(a[l]<=a[h])b[k++]=a[l++];elseb[k++]=a[h++];}if(l>mid)while(h<=high)b[k++]=a[h++];/*转储余下部分*/elsewhile(l<=mid)b[k++]=a[l++];a[low:high]=b[low:high];/*将b数组转储到a*/}●时间复杂度设归并分类的时间复杂度为T(n),存在递归关系:●缺点与改进方法四、比较为基础的分类算法的时间下界结论:以比较为基础的分类算法在最坏情况下的时间下界为O(nlogn),是最坏情况下的最优算法.五、快速分类●原理a[1]…a[j-1]a[j]a[j+1]…a[n]使a[1:j-1]≤a[j]a[j]使a[j+1:n]≥a[j]对a[1:j-1]快速分类a[j]对a[j+1:n]快速分类已分类的集合●实现部分分类的划分过程举例原始41362578指针r=4jk一次循环r=4jkr=41326578二次循环kj交换位置213r=46578k●实现部分分类的划分算法Partition(p,q){r=a[p];j=p+1;k=q;while(1){while((j<=k)&&(a[j]<=r))j++;while((j<=k)&&(a[k]>=r))k--;if(jelsebreak;}a[p]=a[k];a[k]=r;returnk;}●快速分类算法QuickSort(p,q){if(p{j=Partition(p,q);QuickSort(p,j-1);QuickSort(j+1,q);}}●时间复杂度快速分类算法的计算时间C(n)取决于Partition的元素比较次数.在最坏情况下(划分元素取第一个元素),每级Partition(p,q)调用,最多作p-q+1次元素比较,因此,Cw(n)=n+n-1+…+2=O(n2).在平均情况下,假设:n个元素各不相同,划分元素随机选取,取第k(1≤k≤n)个元素是等概率的,因此,存在下列递归关系:(1)(2)用n-1替换(2)中的n,得:(3)(2)-(3)得:nCA(n)-(n-1)CA(n-1)=2n+2CA(n-1)即:CA(n)/(n+1)=CA(n-1)/n+2/(n+1)(4)反复用(4)替换CA(n-1),CA(n-2),…,得到:CA(n)/(n+1)=CA(1)/2+
if(x>a[k])returnBinSearch(k+1,q,x);
四、迭代算法
intBinSearch2(n,x)
{intl=0,h=n-1,k;
while(l<=h)
{k=(l+h)/2;
if(xelseif(x>a[k])l=k+1;elsereturnk;}return–1;} 五、计算复杂度分析1.二元比较树以有序表的中间元素为根节点的二分树,左子树上所有元素不比父节点元素值大,右子树上所有元素不比父节点元素值小.例如,由元素1,2,3,4,5,6,7,8,9构成的有序表,对应的二元比较树内节点,外节点------成功检索,不成功检索二分检索树的深度k=二元比较树的深度k=2.时间复杂度定理2.2若n在区域[2k-1,2k)中,则对于一次成功的检索,BinSearch至多作k次比较;而对于一次不成功的检索,或者作k-1次比较或者作k次比较。成功检索最好情况:O(1)不成功检索最好情况:O(k)=O()=O(logn)成功检索最坏情况:O(k)=O()=O(logn)不成功检索最坏情况:O(k)=O()=O(logn)平均情况分析:内部路径长度之和I,外部路径长度之和E,E=I+2n。成功检索的平均比较次数:S(n)=(I/n)+1不成功检索的平均比较次数:U(n)=E/(n+1)显然,S(n)=(1+1/n)U(n)-1,因为U(n)为O(logn),所以S(n)也为O(logn)。成功检索不成功检索最好最坏平均最好最坏平均O(1)O(logn)O(logn)O(logn)O(logn)O(logn)3.以比较为基础检索的时间下界定理2.3设a[n]含有n(n≥1)个不同元素,排序为a[1]<….由此可见,任何以比较为基础的检索算法,最坏情况下的比较次数都不可能低于O(logn),因此,二分检索是最优的最坏情况算法.2.3找最大和最小元素一、问题在含有n个不同元素的集合a[n]中同时找出它的最大和最小元素.二、直接算法StraitSearch(n,&max,&min){*max=*min=a[0];for(i=1;i{if(a[i]>max)max=a[i];if(a[i]}}比较次数2(n-1),若将语句1改写成if(a[i]>max)max=a[i];elseif(a[i]最好情况n-1,最坏情况2(n-1),平均情况3/2(n-1).三、实现分治策略的递归算法●集合只有一个元素时max=min=a[i]●集合只有两个元素时if(a[i]else{max=a[i];min=a[j];}●集合中有更多元素时将原集合分解成两个子集,分别求两个子集的最大和最小元素,再合并结果.●数据类型typedefstruct{ElemTypemax,min;}SOLUTION;●算法SOLUTIONMaxMin(i,j){SOLUTIONs,s1,s2;if(i==j){s.max=s.min=a[i];returns;}/*一元素*/if(i==j-1)/*两元素*/{if(a[i]else{s.max=a[i];s.min=a[j];}returns;}k=(i+j)/2;s1=MaxMin(i,k);s2=MaxMin(k+1,j);/*多元素时分治*/(s1.max>=s2.max)?(s.max=s1.max):(s.max=s2.max);/*解的合并*/(s1.min<=s2.min)?(s.min=s1.min):(s.min=s2.min);returns;}●时间复杂度令t(n)表示MaxMin需要的元素比较次数,存在下列递推关系当n是2的幂时,即对于某个正整数k,n=2k,有t(n)=2t(n/2)+2=2(2t(n/4)+2)+2=4t(n/4)+4+2=2k-1t(2)+=2k-1+2k-2=3n/2-2注意:当n是2的幂时,3n/2-2是最好、最坏及平均情况下的比较次数,与直接算法的最坏情况相比,少25%.当元素的比较开销与整数比较开销相当时,将MaxMin的前两条if语句合并为:if(i>=j-1)/*对应一元素和两元素的情况*/{if(a[i]else{s.max=a[i];s.min=a[j];}returns;}MaxMin需要的比较次数,存在下列递推关系比StraitSearch算法的3(n-1)低.但MaxMin需要更多存储空间和更多的堆栈操作,实际效率可能更低。四、结论当元素的比较开销比整数比较开销大得多时,MaxMin算法比StraitSearch算法效率高,反之,效率低.因此,分治策略只能看成是一个较好的但并不总是真正好的设计策略。思考题:1.请分析和证明E=I+2n。2.请分析c(n)递推关系式中常数3为什么是3而不是2?2.4分类一、问题给定一个含n个元素的集合a[n],按一定次序(本课程假定均为非降次序)将其分类(排序).二、插入分类●原理已分类的部分未分类的部分a[1]…a[j-1]a[j]a[j+1]…a[n]将未分类的元素逐个插入到已分类部分的正确位置上.●插入分类算法InsertSort(intn){for(j=1;j{for(unsorted=a[j],k=j-1;(k>=0)&&(unsorteda[k+1]=a[k];a[k+1]=unsorted;}}●时间复杂度考虑内层for循环中元素比较的次数T(n):最坏情况T(n)==1+2+…n-1==O(n2)最好情况T(n)=O(n) 三、归并分类●原理a[low]…a[]a[]…a[high]归并分类归并分类按非降次序合并两个已分类的子集●归并分类的递归算法MergeSort(low,high){if(low{mid=(low+high)/2;MergeSort(low,mid);MergeSort(mid+1,high);Merge(low,mid,high);}}●已分类子集的归并过程示例A1345691027811121314指针L=1,K=1,H=8B1指针L=2,H=8,K=2B12指针L=2,H=9,K=3B123456指针L=5,H=9,K=7B12345678指针L=5,H=11,K=9B12345678910指针L=8,H=11,K=11B1234567891011121314指针L=8,H=15,K=15Merge(low,mid,high){ElemTypeb[n];l=low;h=mid+1;k=l;while((l<=mid)&&(h<=high))/*部分合并*/{if(a[l]<=a[h])b[k++]=a[l++];elseb[k++]=a[h++];}if(l>mid)while(h<=high)b[k++]=a[h++];/*转储余下部分*/elsewhile(l<=mid)b[k++]=a[l++];a[low:high]=b[low:high];/*将b数组转储到a*/}●时间复杂度设归并分类的时间复杂度为T(n),存在递归关系:●缺点与改进方法四、比较为基础的分类算法的时间下界结论:以比较为基础的分类算法在最坏情况下的时间下界为O(nlogn),是最坏情况下的最优算法.五、快速分类●原理a[1]…a[j-1]a[j]a[j+1]…a[n]使a[1:j-1]≤a[j]a[j]使a[j+1:n]≥a[j]对a[1:j-1]快速分类a[j]对a[j+1:n]快速分类已分类的集合●实现部分分类的划分过程举例原始41362578指针r=4jk一次循环r=4jkr=41326578二次循环kj交换位置213r=46578k●实现部分分类的划分算法Partition(p,q){r=a[p];j=p+1;k=q;while(1){while((j<=k)&&(a[j]<=r))j++;while((j<=k)&&(a[k]>=r))k--;if(jelsebreak;}a[p]=a[k];a[k]=r;returnk;}●快速分类算法QuickSort(p,q){if(p{j=Partition(p,q);QuickSort(p,j-1);QuickSort(j+1,q);}}●时间复杂度快速分类算法的计算时间C(n)取决于Partition的元素比较次数.在最坏情况下(划分元素取第一个元素),每级Partition(p,q)调用,最多作p-q+1次元素比较,因此,Cw(n)=n+n-1+…+2=O(n2).在平均情况下,假设:n个元素各不相同,划分元素随机选取,取第k(1≤k≤n)个元素是等概率的,因此,存在下列递归关系:(1)(2)用n-1替换(2)中的n,得:(3)(2)-(3)得:nCA(n)-(n-1)CA(n-1)=2n+2CA(n-1)即:CA(n)/(n+1)=CA(n-1)/n+2/(n+1)(4)反复用(4)替换CA(n-1),CA(n-2),…,得到:CA(n)/(n+1)=CA(1)/2+
elseif(x>a[k])l=k+1;
elsereturnk;
return–1;
五、计算复杂度分析
1.二元比较树
以有序表的中间元素为根节点的二分树,左子树上所有元素不比父节点元素值大,右子树上所有元素不比父节点元素值小.
例如,由元素1,2,3,4,5,6,7,8,9构成的有序表,对应的二元比较树
内节点,外节点------成功检索,不成功检索
二分检索树的深度k=
二元比较树的深度k=
2.时间复杂度
定理2.2若n在区域[2k-1,2k)中,则对于一次成功的检索,BinSearch至多作k次比较;而对于一次不成功的检索,或者作k-1次比较或者作k次比较。
成功检索最好情况:
O
(1)
不成功检索最好情况:
O(k)=O(
)=O(logn)
成功检索最坏情况:
不成功检索最坏情况:
平均情况分析:
内部路径长度之和I,外部路径长度之和E,E=I+2n。
成功检索的平均比较次数:
S(n)=(I/n)+1
不成功检索的平均比较次数:
U(n)=E/(n+1)
显然,S(n)=(1+1/n)U(n)-1,因为U(n)为O(logn),所以S(n)也为O(logn)。
成功检索不成功检索
最好最坏平均最好最坏平均
(1)O(logn)O(logn)O(logn)O(logn)O(logn)
3.以比较为基础检索的时间下界
定理2.3设a[n]含有n(n≥1)个不同元素,排序为a[1]<….由此可见,任何以比较为基础的检索算法,最坏情况下的比较次数都不可能低于O(logn),因此,二分检索是最优的最坏情况算法.2.3找最大和最小元素一、问题在含有n个不同元素的集合a[n]中同时找出它的最大和最小元素.二、直接算法StraitSearch(n,&max,&min){*max=*min=a[0];for(i=1;i{if(a[i]>max)max=a[i];if(a[i]}}比较次数2(n-1),若将语句1改写成if(a[i]>max)max=a[i];elseif(a[i]最好情况n-1,最坏情况2(n-1),平均情况3/2(n-1).三、实现分治策略的递归算法●集合只有一个元素时max=min=a[i]●集合只有两个元素时if(a[i]else{max=a[i];min=a[j];}●集合中有更多元素时将原集合分解成两个子集,分别求两个子集的最大和最小元素,再合并结果.●数据类型typedefstruct{ElemTypemax,min;}SOLUTION;●算法SOLUTIONMaxMin(i,j){SOLUTIONs,s1,s2;if(i==j){s.max=s.min=a[i];returns;}/*一元素*/if(i==j-1)/*两元素*/{if(a[i]else{s.max=a[i];s.min=a[j];}returns;}k=(i+j)/2;s1=MaxMin(i,k);s2=MaxMin(k+1,j);/*多元素时分治*/(s1.max>=s2.max)?(s.max=s1.max):(s.max=s2.max);/*解的合并*/(s1.min<=s2.min)?(s.min=s1.min):(s.min=s2.min);returns;}●时间复杂度令t(n)表示MaxMin需要的元素比较次数,存在下列递推关系当n是2的幂时,即对于某个正整数k,n=2k,有t(n)=2t(n/2)+2=2(2t(n/4)+2)+2=4t(n/4)+4+2=2k-1t(2)+=2k-1+2k-2=3n/2-2注意:当n是2的幂时,3n/2-2是最好、最坏及平均情况下的比较次数,与直接算法的最坏情况相比,少25%.当元素的比较开销与整数比较开销相当时,将MaxMin的前两条if语句合并为:if(i>=j-1)/*对应一元素和两元素的情况*/{if(a[i]else{s.max=a[i];s.min=a[j];}returns;}MaxMin需要的比较次数,存在下列递推关系比StraitSearch算法的3(n-1)低.但MaxMin需要更多存储空间和更多的堆栈操作,实际效率可能更低。四、结论当元素的比较开销比整数比较开销大得多时,MaxMin算法比StraitSearch算法效率高,反之,效率低.因此,分治策略只能看成是一个较好的但并不总是真正好的设计策略。思考题:1.请分析和证明E=I+2n。2.请分析c(n)递推关系式中常数3为什么是3而不是2?2.4分类一、问题给定一个含n个元素的集合a[n],按一定次序(本课程假定均为非降次序)将其分类(排序).二、插入分类●原理已分类的部分未分类的部分a[1]…a[j-1]a[j]a[j+1]…a[n]将未分类的元素逐个插入到已分类部分的正确位置上.●插入分类算法InsertSort(intn){for(j=1;j{for(unsorted=a[j],k=j-1;(k>=0)&&(unsorteda[k+1]=a[k];a[k+1]=unsorted;}}●时间复杂度考虑内层for循环中元素比较的次数T(n):最坏情况T(n)==1+2+…n-1==O(n2)最好情况T(n)=O(n) 三、归并分类●原理a[low]…a[]a[]…a[high]归并分类归并分类按非降次序合并两个已分类的子集●归并分类的递归算法MergeSort(low,high){if(low{mid=(low+high)/2;MergeSort(low,mid);MergeSort(mid+1,high);Merge(low,mid,high);}}●已分类子集的归并过程示例A1345691027811121314指针L=1,K=1,H=8B1指针L=2,H=8,K=2B12指针L=2,H=9,K=3B123456指针L=5,H=9,K=7B12345678指针L=5,H=11,K=9B12345678910指针L=8,H=11,K=11B1234567891011121314指针L=8,H=15,K=15Merge(low,mid,high){ElemTypeb[n];l=low;h=mid+1;k=l;while((l<=mid)&&(h<=high))/*部分合并*/{if(a[l]<=a[h])b[k++]=a[l++];elseb[k++]=a[h++];}if(l>mid)while(h<=high)b[k++]=a[h++];/*转储余下部分*/elsewhile(l<=mid)b[k++]=a[l++];a[low:high]=b[low:high];/*将b数组转储到a*/}●时间复杂度设归并分类的时间复杂度为T(n),存在递归关系:●缺点与改进方法四、比较为基础的分类算法的时间下界结论:以比较为基础的分类算法在最坏情况下的时间下界为O(nlogn),是最坏情况下的最优算法.五、快速分类●原理a[1]…a[j-1]a[j]a[j+1]…a[n]使a[1:j-1]≤a[j]a[j]使a[j+1:n]≥a[j]对a[1:j-1]快速分类a[j]对a[j+1:n]快速分类已分类的集合●实现部分分类的划分过程举例原始41362578指针r=4jk一次循环r=4jkr=41326578二次循环kj交换位置213r=46578k●实现部分分类的划分算法Partition(p,q){r=a[p];j=p+1;k=q;while(1){while((j<=k)&&(a[j]<=r))j++;while((j<=k)&&(a[k]>=r))k--;if(jelsebreak;}a[p]=a[k];a[k]=r;returnk;}●快速分类算法QuickSort(p,q){if(p{j=Partition(p,q);QuickSort(p,j-1);QuickSort(j+1,q);}}●时间复杂度快速分类算法的计算时间C(n)取决于Partition的元素比较次数.在最坏情况下(划分元素取第一个元素),每级Partition(p,q)调用,最多作p-q+1次元素比较,因此,Cw(n)=n+n-1+…+2=O(n2).在平均情况下,假设:n个元素各不相同,划分元素随机选取,取第k(1≤k≤n)个元素是等概率的,因此,存在下列递归关系:(1)(2)用n-1替换(2)中的n,得:(3)(2)-(3)得:nCA(n)-(n-1)CA(n-1)=2n+2CA(n-1)即:CA(n)/(n+1)=CA(n-1)/n+2/(n+1)(4)反复用(4)替换CA(n-1),CA(n-2),…,得到:CA(n)/(n+1)=CA(1)/2+
由此可见,任何以比较为基础的检索算法,最坏情况下的比较次数都不可能低于O(logn),因此,二分检索是最优的最坏情况算法.
2.3找最大和最小元素
在含有n个不同元素的集合a[n]中同时找出它的最大和最小元素.
二、直接算法
StraitSearch(n,&max,&min)
{*max=*min=a[0];
for(i=1;i{if(a[i]>max)max=a[i];if(a[i]}}比较次数2(n-1),若将语句1改写成if(a[i]>max)max=a[i];elseif(a[i]最好情况n-1,最坏情况2(n-1),平均情况3/2(n-1).三、实现分治策略的递归算法●集合只有一个元素时max=min=a[i]●集合只有两个元素时if(a[i]else{max=a[i];min=a[j];}●集合中有更多元素时将原集合分解成两个子集,分别求两个子集的最大和最小元素,再合并结果.●数据类型typedefstruct{ElemTypemax,min;}SOLUTION;●算法SOLUTIONMaxMin(i,j){SOLUTIONs,s1,s2;if(i==j){s.max=s.min=a[i];returns;}/*一元素*/if(i==j-1)/*两元素*/{if(a[i]else{s.max=a[i];s.min=a[j];}returns;}k=(i+j)/2;s1=MaxMin(i,k);s2=MaxMin(k+1,j);/*多元素时分治*/(s1.max>=s2.max)?(s.max=s1.max):(s.max=s2.max);/*解的合并*/(s1.min<=s2.min)?(s.min=s1.min):(s.min=s2.min);returns;}●时间复杂度令t(n)表示MaxMin需要的元素比较次数,存在下列递推关系当n是2的幂时,即对于某个正整数k,n=2k,有t(n)=2t(n/2)+2=2(2t(n/4)+2)+2=4t(n/4)+4+2=2k-1t(2)+=2k-1+2k-2=3n/2-2注意:当n是2的幂时,3n/2-2是最好、最坏及平均情况下的比较次数,与直接算法的最坏情况相比,少25%.当元素的比较开销与整数比较开销相当时,将MaxMin的前两条if语句合并为:if(i>=j-1)/*对应一元素和两元素的情况*/{if(a[i]else{s.max=a[i];s.min=a[j];}returns;}MaxMin需要的比较次数,存在下列递推关系比StraitSearch算法的3(n-1)低.但MaxMin需要更多存储空间和更多的堆栈操作,实际效率可能更低。四、结论当元素的比较开销比整数比较开销大得多时,MaxMin算法比StraitSearch算法效率高,反之,效率低.因此,分治策略只能看成是一个较好的但并不总是真正好的设计策略。思考题:1.请分析和证明E=I+2n。2.请分析c(n)递推关系式中常数3为什么是3而不是2?2.4分类一、问题给定一个含n个元素的集合a[n],按一定次序(本课程假定均为非降次序)将其分类(排序).二、插入分类●原理已分类的部分未分类的部分a[1]…a[j-1]a[j]a[j+1]…a[n]将未分类的元素逐个插入到已分类部分的正确位置上.●插入分类算法InsertSort(intn){for(j=1;j{for(unsorted=a[j],k=j-1;(k>=0)&&(unsorteda[k+1]=a[k];a[k+1]=unsorted;}}●时间复杂度考虑内层for循环中元素比较的次数T(n):最坏情况T(n)==1+2+…n-1==O(n2)最好情况T(n)=O(n) 三、归并分类●原理a[low]…a[]a[]…a[high]归并分类归并分类按非降次序合并两个已分类的子集●归并分类的递归算法MergeSort(low,high){if(low{mid=(low+high)/2;MergeSort(low,mid);MergeSort(mid+1,high);Merge(low,mid,high);}}●已分类子集的归并过程示例A1345691027811121314指针L=1,K=1,H=8B1指针L=2,H=8,K=2B12指针L=2,H=9,K=3B123456指针L=5,H=9,K=7B12345678指针L=5,H=11,K=9B12345678910指针L=8,H=11,K=11B1234567891011121314指针L=8,H=15,K=15Merge(low,mid,high){ElemTypeb[n];l=low;h=mid+1;k=l;while((l<=mid)&&(h<=high))/*部分合并*/{if(a[l]<=a[h])b[k++]=a[l++];elseb[k++]=a[h++];}if(l>mid)while(h<=high)b[k++]=a[h++];/*转储余下部分*/elsewhile(l<=mid)b[k++]=a[l++];a[low:high]=b[low:high];/*将b数组转储到a*/}●时间复杂度设归并分类的时间复杂度为T(n),存在递归关系:●缺点与改进方法四、比较为基础的分类算法的时间下界结论:以比较为基础的分类算法在最坏情况下的时间下界为O(nlogn),是最坏情况下的最优算法.五、快速分类●原理a[1]…a[j-1]a[j]a[j+1]…a[n]使a[1:j-1]≤a[j]a[j]使a[j+1:n]≥a[j]对a[1:j-1]快速分类a[j]对a[j+1:n]快速分类已分类的集合●实现部分分类的划分过程举例原始41362578指针r=4jk一次循环r=4jkr=41326578二次循环kj交换位置213r=46578k●实现部分分类的划分算法Partition(p,q){r=a[p];j=p+1;k=q;while(1){while((j<=k)&&(a[j]<=r))j++;while((j<=k)&&(a[k]>=r))k--;if(jelsebreak;}a[p]=a[k];a[k]=r;returnk;}●快速分类算法QuickSort(p,q){if(p{j=Partition(p,q);QuickSort(p,j-1);QuickSort(j+1,q);}}●时间复杂度快速分类算法的计算时间C(n)取决于Partition的元素比较次数.在最坏情况下(划分元素取第一个元素),每级Partition(p,q)调用,最多作p-q+1次元素比较,因此,Cw(n)=n+n-1+…+2=O(n2).在平均情况下,假设:n个元素各不相同,划分元素随机选取,取第k(1≤k≤n)个元素是等概率的,因此,存在下列递归关系:(1)(2)用n-1替换(2)中的n,得:(3)(2)-(3)得:nCA(n)-(n-1)CA(n-1)=2n+2CA(n-1)即:CA(n)/(n+1)=CA(n-1)/n+2/(n+1)(4)反复用(4)替换CA(n-1),CA(n-2),…,得到:CA(n)/(n+1)=CA(1)/2+
{if(a[i]>max)max=a[i];
if(a[i]}}比较次数2(n-1),若将语句1改写成if(a[i]>max)max=a[i];elseif(a[i]最好情况n-1,最坏情况2(n-1),平均情况3/2(n-1).三、实现分治策略的递归算法●集合只有一个元素时max=min=a[i]●集合只有两个元素时if(a[i]else{max=a[i];min=a[j];}●集合中有更多元素时将原集合分解成两个子集,分别求两个子集的最大和最小元素,再合并结果.●数据类型typedefstruct{ElemTypemax,min;}SOLUTION;●算法SOLUTIONMaxMin(i,j){SOLUTIONs,s1,s2;if(i==j){s.max=s.min=a[i];returns;}/*一元素*/if(i==j-1)/*两元素*/{if(a[i]else{s.max=a[i];s.min=a[j];}returns;}k=(i+j)/2;s1=MaxMin(i,k);s2=MaxMin(k+1,j);/*多元素时分治*/(s1.max>=s2.max)?(s.max=s1.max):(s.max=s2.max);/*解的合并*/(s1.min<=s2.min)?(s.min=s1.min):(s.min=s2.min);returns;}●时间复杂度令t(n)表示MaxMin需要的元素比较次数,存在下列递推关系当n是2的幂时,即对于某个正整数k,n=2k,有t(n)=2t(n/2)+2=2(2t(n/4)+2)+2=4t(n/4)+4+2=2k-1t(2)+=2k-1+2k-2=3n/2-2注意:当n是2的幂时,3n/2-2是最好、最坏及平均情况下的比较次数,与直接算法的最坏情况相比,少25%.当元素的比较开销与整数比较开销相当时,将MaxMin的前两条if语句合并为:if(i>=j-1)/*对应一元素和两元素的情况*/{if(a[i]else{s.max=a[i];s.min=a[j];}returns;}MaxMin需要的比较次数,存在下列递推关系比StraitSearch算法的3(n-1)低.但MaxMin需要更多存储空间和更多的堆栈操作,实际效率可能更低。四、结论当元素的比较开销比整数比较开销大得多时,MaxMin算法比StraitSearch算法效率高,反之,效率低.因此,分治策略只能看成是一个较好的但并不总是真正好的设计策略。思考题:1.请分析和证明E=I+2n。2.请分析c(n)递推关系式中常数3为什么是3而不是2?2.4分类一、问题给定一个含n个元素的集合a[n],按一定次序(本课程假定均为非降次序)将其分类(排序).二、插入分类●原理已分类的部分未分类的部分a[1]…a[j-1]a[j]a[j+1]…a[n]将未分类的元素逐个插入到已分类部分的正确位置上.●插入分类算法InsertSort(intn){for(j=1;j{for(unsorted=a[j],k=j-1;(k>=0)&&(unsorteda[k+1]=a[k];a[k+1]=unsorted;}}●时间复杂度考虑内层for循环中元素比较的次数T(n):最坏情况T(n)==1+2+…n-1==O(n2)最好情况T(n)=O(n) 三、归并分类●原理a[low]…a[]a[]…a[high]归并分类归并分类按非降次序合并两个已分类的子集●归并分类的递归算法MergeSort(low,high){if(low{mid=(low+high)/2;MergeSort(low,mid);MergeSort(mid+1,high);Merge(low,mid,high);}}●已分类子集的归并过程示例A1345691027811121314指针L=1,K=1,H=8B1指针L=2,H=8,K=2B12指针L=2,H=9,K=3B123456指针L=5,H=9,K=7B12345678指针L=5,H=11,K=9B12345678910指针L=8,H=11,K=11B1234567891011121314指针L=8,H=15,K=15Merge(low,mid,high){ElemTypeb[n];l=low;h=mid+1;k=l;while((l<=mid)&&(h<=high))/*部分合并*/{if(a[l]<=a[h])b[k++]=a[l++];elseb[k++]=a[h++];}if(l>mid)while(h<=high)b[k++]=a[h++];/*转储余下部分*/elsewhile(l<=mid)b[k++]=a[l++];a[low:high]=b[low:high];/*将b数组转储到a*/}●时间复杂度设归并分类的时间复杂度为T(n),存在递归关系:●缺点与改进方法四、比较为基础的分类算法的时间下界结论:以比较为基础的分类算法在最坏情况下的时间下界为O(nlogn),是最坏情况下的最优算法.五、快速分类●原理a[1]…a[j-1]a[j]a[j+1]…a[n]使a[1:j-1]≤a[j]a[j]使a[j+1:n]≥a[j]对a[1:j-1]快速分类a[j]对a[j+1:n]快速分类已分类的集合●实现部分分类的划分过程举例原始41362578指针r=4jk一次循环r=4jkr=41326578二次循环kj交换位置213r=46578k●实现部分分类的划分算法Partition(p,q){r=a[p];j=p+1;k=q;while(1){while((j<=k)&&(a[j]<=r))j++;while((j<=k)&&(a[k]>=r))k--;if(jelsebreak;}a[p]=a[k];a[k]=r;returnk;}●快速分类算法QuickSort(p,q){if(p{j=Partition(p,q);QuickSort(p,j-1);QuickSort(j+1,q);}}●时间复杂度快速分类算法的计算时间C(n)取决于Partition的元素比较次数.在最坏情况下(划分元素取第一个元素),每级Partition(p,q)调用,最多作p-q+1次元素比较,因此,Cw(n)=n+n-1+…+2=O(n2).在平均情况下,假设:n个元素各不相同,划分元素随机选取,取第k(1≤k≤n)个元素是等概率的,因此,存在下列递归关系:(1)(2)用n-1替换(2)中的n,得:(3)(2)-(3)得:nCA(n)-(n-1)CA(n-1)=2n+2CA(n-1)即:CA(n)/(n+1)=CA(n-1)/n+2/(n+1)(4)反复用(4)替换CA(n-1),CA(n-2),…,得到:CA(n)/(n+1)=CA(1)/2+
比较次数2(n-1),若将语句1改写成
if(a[i]>max)max=a[i];
elseif(a[i]最好情况n-1,最坏情况2(n-1),平均情况3/2(n-1).三、实现分治策略的递归算法●集合只有一个元素时max=min=a[i]●集合只有两个元素时if(a[i]else{max=a[i];min=a[j];}●集合中有更多元素时将原集合分解成两个子集,分别求两个子集的最大和最小元素,再合并结果.●数据类型typedefstruct{ElemTypemax,min;}SOLUTION;●算法SOLUTIONMaxMin(i,j){SOLUTIONs,s1,s2;if(i==j){s.max=s.min=a[i];returns;}/*一元素*/if(i==j-1)/*两元素*/{if(a[i]else{s.max=a[i];s.min=a[j];}returns;}k=(i+j)/2;s1=MaxMin(i,k);s2=MaxMin(k+1,j);/*多元素时分治*/(s1.max>=s2.max)?(s.max=s1.max):(s.max=s2.max);/*解的合并*/(s1.min<=s2.min)?(s.min=s1.min):(s.min=s2.min);returns;}●时间复杂度令t(n)表示MaxMin需要的元素比较次数,存在下列递推关系当n是2的幂时,即对于某个正整数k,n=2k,有t(n)=2t(n/2)+2=2(2t(n/4)+2)+2=4t(n/4)+4+2=2k-1t(2)+=2k-1+2k-2=3n/2-2注意:当n是2的幂时,3n/2-2是最好、最坏及平均情况下的比较次数,与直接算法的最坏情况相比,少25%.当元素的比较开销与整数比较开销相当时,将MaxMin的前两条if语句合并为:if(i>=j-1)/*对应一元素和两元素的情况*/{if(a[i]else{s.max=a[i];s.min=a[j];}returns;}MaxMin需要的比较次数,存在下列递推关系比StraitSearch算法的3(n-1)低.但MaxMin需要更多存储空间和更多的堆栈操作,实际效率可能更低。四、结论当元素的比较开销比整数比较开销大得多时,MaxMin算法比StraitSearch算法效率高,反之,效率低.因此,分治策略只能看成是一个较好的但并不总是真正好的设计策略。思考题:1.请分析和证明E=I+2n。2.请分析c(n)递推关系式中常数3为什么是3而不是2?2.4分类一、问题给定一个含n个元素的集合a[n],按一定次序(本课程假定均为非降次序)将其分类(排序).二、插入分类●原理已分类的部分未分类的部分a[1]…a[j-1]a[j]a[j+1]…a[n]将未分类的元素逐个插入到已分类部分的正确位置上.●插入分类算法InsertSort(intn){for(j=1;j{for(unsorted=a[j],k=j-1;(k>=0)&&(unsorteda[k+1]=a[k];a[k+1]=unsorted;}}●时间复杂度考虑内层for循环中元素比较的次数T(n):最坏情况T(n)==1+2+…n-1==O(n2)最好情况T(n)=O(n) 三、归并分类●原理a[low]…a[]a[]…a[high]归并分类归并分类按非降次序合并两个已分类的子集●归并分类的递归算法MergeSort(low,high){if(low{mid=(low+high)/2;MergeSort(low,mid);MergeSort(mid+1,high);Merge(low,mid,high);}}●已分类子集的归并过程示例A1345691027811121314指针L=1,K=1,H=8B1指针L=2,H=8,K=2B12指针L=2,H=9,K=3B123456指针L=5,H=9,K=7B12345678指针L=5,H=11,K=9B12345678910指针L=8,H=11,K=11B1234567891011121314指针L=8,H=15,K=15Merge(low,mid,high){ElemTypeb[n];l=low;h=mid+1;k=l;while((l<=mid)&&(h<=high))/*部分合并*/{if(a[l]<=a[h])b[k++]=a[l++];elseb[k++]=a[h++];}if(l>mid)while(h<=high)b[k++]=a[h++];/*转储余下部分*/elsewhile(l<=mid)b[k++]=a[l++];a[low:high]=b[low:high];/*将b数组转储到a*/}●时间复杂度设归并分类的时间复杂度为T(n),存在递归关系:●缺点与改进方法四、比较为基础的分类算法的时间下界结论:以比较为基础的分类算法在最坏情况下的时间下界为O(nlogn),是最坏情况下的最优算法.五、快速分类●原理a[1]…a[j-1]a[j]a[j+1]…a[n]使a[1:j-1]≤a[j]a[j]使a[j+1:n]≥a[j]对a[1:j-1]快速分类a[j]对a[j+1:n]快速分类已分类的集合●实现部分分类的划分过程举例原始41362578指针r=4jk一次循环r=4jkr=41326578二次循环kj交换位置213r=46578k●实现部分分类的划分算法Partition(p,q){r=a[p];j=p+1;k=q;while(1){while((j<=k)&&(a[j]<=r))j++;while((j<=k)&&(a[k]>=r))k--;if(jelsebreak;}a[p]=a[k];a[k]=r;returnk;}●快速分类算法QuickSort(p,q){if(p{j=Partition(p,q);QuickSort(p,j-1);QuickSort(j+1,q);}}●时间复杂度快速分类算法的计算时间C(n)取决于Partition的元素比较次数.在最坏情况下(划分元素取第一个元素),每级Partition(p,q)调用,最多作p-q+1次元素比较,因此,Cw(n)=n+n-1+…+2=O(n2).在平均情况下,假设:n个元素各不相同,划分元素随机选取,取第k(1≤k≤n)个元素是等概率的,因此,存在下列递归关系:(1)(2)用n-1替换(2)中的n,得:(3)(2)-(3)得:nCA(n)-(n-1)CA(n-1)=2n+2CA(n-1)即:CA(n)/(n+1)=CA(n-1)/n+2/(n+1)(4)反复用(4)替换CA(n-1),CA(n-2),…,得到:CA(n)/(n+1)=CA(1)/2+
最好情况n-1,最坏情况2(n-1),平均情况3/2(n-1).
三、实现分治策略的递归算法
●集合只有一个元素时
max=min=a[i]
●集合只有两个元素时
if(a[i]else{max=a[i];min=a[j];}●集合中有更多元素时将原集合分解成两个子集,分别求两个子集的最大和最小元素,再合并结果.●数据类型typedefstruct{ElemTypemax,min;}SOLUTION;●算法SOLUTIONMaxMin(i,j){SOLUTIONs,s1,s2;if(i==j){s.max=s.min=a[i];returns;}/*一元素*/if(i==j-1)/*两元素*/{if(a[i]else{s.max=a[i];s.min=a[j];}returns;}k=(i+j)/2;s1=MaxMin(i,k);s2=MaxMin(k+1,j);/*多元素时分治*/(s1.max>=s2.max)?(s.max=s1.max):(s.max=s2.max);/*解的合并*/(s1.min<=s2.min)?(s.min=s1.min):(s.min=s2.min);returns;}●时间复杂度令t(n)表示MaxMin需要的元素比较次数,存在下列递推关系当n是2的幂时,即对于某个正整数k,n=2k,有t(n)=2t(n/2)+2=2(2t(n/4)+2)+2=4t(n/4)+4+2=2k-1t(2)+=2k-1+2k-2=3n/2-2注意:当n是2的幂时,3n/2-2是最好、最坏及平均情况下的比较次数,与直接算法的最坏情况相比,少25%.当元素的比较开销与整数比较开销相当时,将MaxMin的前两条if语句合并为:if(i>=j-1)/*对应一元素和两元素的情况*/{if(a[i]else{s.max=a[i];s.min=a[j];}returns;}MaxMin需要的比较次数,存在下列递推关系比StraitSearch算法的3(n-1)低.但MaxMin需要更多存储空间和更多的堆栈操作,实际效率可能更低。四、结论当元素的比较开销比整数比较开销大得多时,MaxMin算法比StraitSearch算法效率高,反之,效率低.因此,分治策略只能看成是一个较好的但并不总是真正好的设计策略。思考题:1.请分析和证明E=I+2n。2.请分析c(n)递推关系式中常数3为什么是3而不是2?2.4分类一、问题给定一个含n个元素的集合a[n],按一定次序(本课程假定均为非降次序)将其分类(排序).二、插入分类●原理已分类的部分未分类的部分a[1]…a[j-1]a[j]a[j+1]…a[n]将未分类的元素逐个插入到已分类部分的正确位置上.●插入分类算法InsertSort(intn){for(j=1;j{for(unsorted=a[j],k=j-1;(k>=0)&&(unsorteda[k+1]=a[k];a[k+1]=unsorted;}}●时间复杂度考虑内层for循环中元素比较的次数T(n):最坏情况T(n)==1+2+…n-1==O(n2)最好情况T(n)=O(n) 三、归并分类●原理a[low]…a[]a[]…a[high]归并分类归并分类按非降次序合并两个已分类的子集●归并分类的递归算法MergeSort(low,high){if(low{mid=(low+high)/2;MergeSort(low,mid);MergeSort(mid+1,high);Merge(low,mid,high);}}●已分类子集的归并过程示例A1345691027811121314指针L=1,K=1,H=8B1指针L=2,H=8,K=2B12指针L=2,H=9,K=3B123456指针L=5,H=9,K=7B12345678指针L=5,H=11,K=9B12345678910指针L=8,H=11,K=11B1234567891011121314指针L=8,H=15,K=15Merge(low,mid,high){ElemTypeb[n];l=low;h=mid+1;k=l;while((l<=mid)&&(h<=high))/*部分合并*/{if(a[l]<=a[h])b[k++]=a[l++];elseb[k++]=a[h++];}if(l>mid)while(h<=high)b[k++]=a[h++];/*转储余下部分*/elsewhile(l<=mid)b[k++]=a[l++];a[low:high]=b[low:high];/*将b数组转储到a*/}●时间复杂度设归并分类的时间复杂度为T(n),存在递归关系:●缺点与改进方法四、比较为基础的分类算法的时间下界结论:以比较为基础的分类算法在最坏情况下的时间下界为O(nlogn),是最坏情况下的最优算法.五、快速分类●原理a[1]…a[j-1]a[j]a[j+1]…a[n]使a[1:j-1]≤a[j]a[j]使a[j+1:n]≥a[j]对a[1:j-1]快速分类a[j]对a[j+1:n]快速分类已分类的集合●实现部分分类的划分过程举例原始41362578指针r=4jk一次循环r=4jkr=41326578二次循环kj交换位置213r=46578k●实现部分分类的划分算法Partition(p,q){r=a[p];j=p+1;k=q;while(1){while((j<=k)&&(a[j]<=r))j++;while((j<=k)&&(a[k]>=r))k--;if(jelsebreak;}a[p]=a[k];a[k]=r;returnk;}●快速分类算法QuickSort(p,q){if(p{j=Partition(p,q);QuickSort(p,j-1);QuickSort(j+1,q);}}●时间复杂度快速分类算法的计算时间C(n)取决于Partition的元素比较次数.在最坏情况下(划分元素取第一个元素),每级Partition(p,q)调用,最多作p-q+1次元素比较,因此,Cw(n)=n+n-1+…+2=O(n2).在平均情况下,假设:n个元素各不相同,划分元素随机选取,取第k(1≤k≤n)个元素是等概率的,因此,存在下列递归关系:(1)(2)用n-1替换(2)中的n,得:(3)(2)-(3)得:nCA(n)-(n-1)CA(n-1)=2n+2CA(n-1)即:CA(n)/(n+1)=CA(n-1)/n+2/(n+1)(4)反复用(4)替换CA(n-1),CA(n-2),…,得到:CA(n)/(n+1)=CA(1)/2+
else{max=a[i];min=a[j];}
●集合中有更多元素时
将原集合分解成两个子集,分别求两个子集的最大和最小元素,再合并结果.
●数据类型
typedefstruct{ElemTypemax,min;}SOLUTION;
●算法
SOLUTIONMaxMin(i,j)
{SOLUTIONs,s1,s2;
if(i==j){s.max=s.min=a[i];returns;}/*一元素*/
if(i==j-1)/*两元素*/
{if(a[i]else{s.max=a[i];s.min=a[j];}returns;}k=(i+j)/2;s1=MaxMin(i,k);s2=MaxMin(k+1,j);/*多元素时分治*/(s1.max>=s2.max)?(s.max=s1.max):(s.max=s2.max);/*解的合并*/(s1.min<=s2.min)?(s.min=s1.min):(s.min=s2.min);returns;}●时间复杂度令t(n)表示MaxMin需要的元素比较次数,存在下列递推关系当n是2的幂时,即对于某个正整数k,n=2k,有t(n)=2t(n/2)+2=2(2t(n/4)+2)+2=4t(n/4)+4+2=2k-1t(2)+=2k-1+2k-2=3n/2-2注意:当n是2的幂时,3n/2-2是最好、最坏及平均情况下的比较次数,与直接算法的最坏情况相比,少25%.当元素的比较开销与整数比较开销相当时,将MaxMin的前两条if语句合并为:if(i>=j-1)/*对应一元素和两元素的情况*/{if(a[i]else{s.max=a[i];s.min=a[j];}returns;}MaxMin需要的比较次数,存在下列递推关系比StraitSearch算法的3(n-1)低.但MaxMin需要更多存储空间和更多的堆栈操作,实际效率可能更低。四、结论当元素的比较开销比整数比较开销大得多时,MaxMin算法比StraitSearch算法效率高,反之,效率低.因此,分治策略只能看成是一个较好的但并不总是真正好的设计策略。思考题:1.请分析和证明E=I+2n。2.请分析c(n)递推关系式中常数3为什么是3而不是2?2.4分类一、问题给定一个含n个元素的集合a[n],按一定次序(本课程假定均为非降次序)将其分类(排序).二、插入分类●原理已分类的部分未分类的部分a[1]…a[j-1]a[j]a[j+1]…a[n]将未分类的元素逐个插入到已分类部分的正确位置上.●插入分类算法InsertSort(intn){for(j=1;j{for(unsorted=a[j],k=j-1;(k>=0)&&(unsorteda[k+1]=a[k];a[k+1]=unsorted;}}●时间复杂度考虑内层for循环中元素比较的次数T(n):最坏情况T(n)==1+2+…n-1==O(n2)最好情况T(n)=O(n) 三、归并分类●原理a[low]…a[]a[]…a[high]归并分类归并分类按非降次序合并两个已分类的子集●归并分类的递归算法MergeSort(low,high){if(low{mid=(low+high)/2;MergeSort(low,mid);MergeSort(mid+1,high);Merge(low,mid,high);}}●已分类子集的归并过程示例A1345691027811121314指针L=1,K=1,H=8B1指针L=2,H=8,K=2B12指针L=2,H=9,K=3B123456指针L=5,H=9,K=7B12345678指针L=5,H=11,K=9B12345678910指针L=8,H=11,K=11B1234567891011121314指针L=8,H=15,K=15Merge(low,mid,high){ElemTypeb[n];l=low;h=mid+1;k=l;while((l<=mid)&&(h<=high))/*部分合并*/{if(a[l]<=a[h])b[k++]=a[l++];elseb[k++]=a[h++];}if(l>mid)while(h<=high)b[k++]=a[h++];/*转储余下部分*/elsewhile(l<=mid)b[k++]=a[l++];a[low:high]=b[low:high];/*将b数组转储到a*/}●时间复杂度设归并分类的时间复杂度为T(n),存在递归关系:●缺点与改进方法四、比较为基础的分类算法的时间下界结论:以比较为基础的分类算法在最坏情况下的时间下界为O(nlogn),是最坏情况下的最优算法.五、快速分类●原理a[1]…a[j-1]a[j]a[j+1]…a[n]使a[1:j-1]≤a[j]a[j]使a[j+1:n]≥a[j]对a[1:j-1]快速分类a[j]对a[j+1:n]快速分类已分类的集合●实现部分分类的划分过程举例原始41362578指针r=4jk一次循环r=4jkr=41326578二次循环kj交换位置213r=46578k●实现部分分类的划分算法Partition(p,q){r=a[p];j=p+1;k=q;while(1){while((j<=k)&&(a[j]<=r))j++;while((j<=k)&&(a[k]>=r))k--;if(jelsebreak;}a[p]=a[k];a[k]=r;returnk;}●快速分类算法QuickSort(p,q){if(p{j=Partition(p,q);QuickSort(p,j-1);QuickSort(j+1,q);}}●时间复杂度快速分类算法的计算时间C(n)取决于Partition的元素比较次数.在最坏情况下(划分元素取第一个元素),每级Partition(p,q)调用,最多作p-q+1次元素比较,因此,Cw(n)=n+n-1+…+2=O(n2).在平均情况下,假设:n个元素各不相同,划分元素随机选取,取第k(1≤k≤n)个元素是等概率的,因此,存在下列递归关系:(1)(2)用n-1替换(2)中的n,得:(3)(2)-(3)得:nCA(n)-(n-1)CA(n-1)=2n+2CA(n-1)即:CA(n)/(n+1)=CA(n-1)/n+2/(n+1)(4)反复用(4)替换CA(n-1),CA(n-2),…,得到:CA(n)/(n+1)=CA(1)/2+
else{s.max=a[i];s.min=a[j];}
returns;
k=(i+j)/2;s1=MaxMin(i,k);s2=MaxMin(k+1,j);/*多元素时分治*/
(s1.max>=s2.max)?
(s.max=s1.max):
(s.max=s2.max);/*解的合并*/
(s1.min<=s2.min)?
(s.min=s1.min):
(s.min=s2.min);
●时间复杂度
令t(n)表示MaxMin需要的元素比较次数,存在下列递推关系
当n是2的幂时,即对于某个正整数k,n=2k,有
t(n)=2t(n/2)+2=2(2t(n/4)+2)+2=4t(n/4)+4+2
=2k-1t
(2)+
=2k-1+2k-2
=3n/2-2
注意:
当n是2的幂时,3n/2-2是最好、最坏及平均情况下的比较次数,与直接算法的最坏情况相比,少25%.
当元素的比较开销与整数比较开销相当时,将MaxMin的前两条if语句合并为:
if(i>=j-1)/*对应一元素和两元素的情况*/
{if(a[i]else{s.max=a[i];s.min=a[j];}returns;}MaxMin需要的比较次数,存在下列递推关系比StraitSearch算法的3(n-1)低.但MaxMin需要更多存储空间和更多的堆栈操作,实际效率可能更低。四、结论当元素的比较开销比整数比较开销大得多时,MaxMin算法比StraitSearch算法效率高,反之,效率低.因此,分治策略只能看成是一个较好的但并不总是真正好的设计策略。思考题:1.请分析和证明E=I+2n。2.请分析c(n)递推关系式中常数3为什么是3而不是2?2.4分类一、问题给定一个含n个元素的集合a[n],按一定次序(本课程假定均为非降次序)将其分类(排序).二、插入分类●原理已分类的部分未分类的部分a[1]…a[j-1]a[j]a[j+1]…a[n]将未分类的元素逐个插入到已分类部分的正确位置上.●插入分类算法InsertSort(intn){for(j=1;j{for(unsorted=a[j],k=j-1;(k>=0)&&(unsorteda[k+1]=a[k];a[k+1]=unsorted;}}●时间复杂度考虑内层for循环中元素比较的次数T(n):最坏情况T(n)==1+2+…n-1==O(n2)最好情况T(n)=O(n) 三、归并分类●原理a[low]…a[]a[]…a[high]归并分类归并分类按非降次序合并两个已分类的子集●归并分类的递归算法MergeSort(low,high){if(low{mid=(low+high)/2;MergeSort(low,mid);MergeSort(mid+1,high);Merge(low,mid,high);}}●已分类子集的归并过程示例A1345691027811121314指针L=1,K=1,H=8B1指针L=2,H=8,K=2B12指针L=2,H=9,K=3B123456指针L=5,H=9,K=7B12345678指针L=5,H=11,K=9B12345678910指针L=8,H=11,K=11B1234567891011121314指针L=8,H=15,K=15Merge(low,mid,high){ElemTypeb[n];l=low;h=mid+1;k=l;while((l<=mid)&&(h<=high))/*部分合并*/{if(a[l]<=a[h])b[k++]=a[l++];elseb[k++]=a[h++];}if(l>mid)while(h<=high)b[k++]=a[h++];/*转储余下部分*/elsewhile(l<=mid)b[k++]=a[l++];a[low:high]=b[low:high];/*将b数组转储到a*/}●时间复杂度设归并分类的时间复杂度为T(n),存在递归关系:●缺点与改进方法四、比较为基础的分类算法的时间下界结论:以比较为基础的分类算法在最坏情况下的时间下界为O(nlogn),是最坏情况下的最优算法.五、快速分类●原理a[1]…a[j-1]a[j]a[j+1]…a[n]使a[1:j-1]≤a[j]a[j]使a[j+1:n]≥a[j]对a[1:j-1]快速分类a[j]对a[j+1:n]快速分类已分类的集合●实现部分分类的划分过程举例原始41362578指针r=4jk一次循环r=4jkr=41326578二次循环kj交换位置213r=46578k●实现部分分类的划分算法Partition(p,q){r=a[p];j=p+1;k=q;while(1){while((j<=k)&&(a[j]<=r))j++;while((j<=k)&&(a[k]>=r))k--;if(jelsebreak;}a[p]=a[k];a[k]=r;returnk;}●快速分类算法QuickSort(p,q){if(p{j=Partition(p,q);QuickSort(p,j-1);QuickSort(j+1,q);}}●时间复杂度快速分类算法的计算时间C(n)取决于Partition的元素比较次数.在最坏情况下(划分元素取第一个元素),每级Partition(p,q)调用,最多作p-q+1次元素比较,因此,Cw(n)=n+n-1+…+2=O(n2).在平均情况下,假设:n个元素各不相同,划分元素随机选取,取第k(1≤k≤n)个元素是等概率的,因此,存在下列递归关系:(1)(2)用n-1替换(2)中的n,得:(3)(2)-(3)得:nCA(n)-(n-1)CA(n-1)=2n+2CA(n-1)即:CA(n)/(n+1)=CA(n-1)/n+2/(n+1)(4)反复用(4)替换CA(n-1),CA(n-2),…,得到:CA(n)/(n+1)=CA(1)/2+
MaxMin需要的比较次数,存在下列递推关系
比StraitSearch算法的3(n-1)低.但MaxMin需要更多存储空间和更多的堆栈操作,实际效率可能更低。
四、结论
当元素的比较开销比整数比较开销大得多时,MaxMin算法比StraitSearch算法效率高,反之,效率低.因此,分治策略只能看成是一个较好的但并不总是真正好的设计策略。
1.请分析和证明E=I+2n。
2.请分析c(n)递推关系式中常数3为什么是3而不是2?
2.4分类
给定一个含n个元素的集合a[n],按一定次序(本课程假定均为非降次序)将其分类(排序).
二、插入分类
●原理
已分类的部分
未分类的部分
a[1]
…
a[j-1]
a[j]
a[j+1]
a[n]
将未分类的元素逐个插入到已分类部分的正确位置上.
●插入分类算法
InsertSort(intn)
{for(j=1;j{for(unsorted=a[j],k=j-1;(k>=0)&&(unsorteda[k+1]=a[k];a[k+1]=unsorted;}}●时间复杂度考虑内层for循环中元素比较的次数T(n):最坏情况T(n)==1+2+…n-1==O(n2)最好情况T(n)=O(n) 三、归并分类●原理a[low]…a[]a[]…a[high]归并分类归并分类按非降次序合并两个已分类的子集●归并分类的递归算法MergeSort(low,high){if(low{mid=(low+high)/2;MergeSort(low,mid);MergeSort(mid+1,high);Merge(low,mid,high);}}●已分类子集的归并过程示例A1345691027811121314指针L=1,K=1,H=8B1指针L=2,H=8,K=2B12指针L=2,H=9,K=3B123456指针L=5,H=9,K=7B12345678指针L=5,H=11,K=9B12345678910指针L=8,H=11,K=11B1234567891011121314指针L=8,H=15,K=15Merge(low,mid,high){ElemTypeb[n];l=low;h=mid+1;k=l;while((l<=mid)&&(h<=high))/*部分合并*/{if(a[l]<=a[h])b[k++]=a[l++];elseb[k++]=a[h++];}if(l>mid)while(h<=high)b[k++]=a[h++];/*转储余下部分*/elsewhile(l<=mid)b[k++]=a[l++];a[low:high]=b[low:high];/*将b数组转储到a*/}●时间复杂度设归并分类的时间复杂度为T(n),存在递归关系:●缺点与改进方法四、比较为基础的分类算法的时间下界结论:以比较为基础的分类算法在最坏情况下的时间下界为O(nlogn),是最坏情况下的最优算法.五、快速分类●原理a[1]…a[j-1]a[j]a[j+1]…a[n]使a[1:j-1]≤a[j]a[j]使a[j+1:n]≥a[j]对a[1:j-1]快速分类a[j]对a[j+1:n]快速分类已分类的集合●实现部分分类的划分过程举例原始41362578指针r=4jk一次循环r=4jkr=41326578二次循环kj交换位置213r=46578k●实现部分分类的划分算法Partition(p,q){r=a[p];j=p+1;k=q;while(1){while((j<=k)&&(a[j]<=r))j++;while((j<=k)&&(a[k]>=r))k--;if(jelsebreak;}a[p]=a[k];a[k]=r;returnk;}●快速分类算法QuickSort(p,q){if(p{j=Partition(p,q);QuickSort(p,j-1);QuickSort(j+1,q);}}●时间复杂度快速分类算法的计算时间C(n)取决于Partition的元素比较次数.在最坏情况下(划分元素取第一个元素),每级Partition(p,q)调用,最多作p-q+1次元素比较,因此,Cw(n)=n+n-1+…+2=O(n2).在平均情况下,假设:n个元素各不相同,划分元素随机选取,取第k(1≤k≤n)个元素是等概率的,因此,存在下列递归关系:(1)(2)用n-1替换(2)中的n,得:(3)(2)-(3)得:nCA(n)-(n-1)CA(n-1)=2n+2CA(n-1)即:CA(n)/(n+1)=CA(n-1)/n+2/(n+1)(4)反复用(4)替换CA(n-1),CA(n-2),…,得到:CA(n)/(n+1)=CA(1)/2+
{for(unsorted=a[j],k=j-1;(k>=0)&&(unsorteda[k+1]=a[k];a[k+1]=unsorted;}}●时间复杂度考虑内层for循环中元素比较的次数T(n):最坏情况T(n)==1+2+…n-1==O(n2)最好情况T(n)=O(n) 三、归并分类●原理a[low]…a[]a[]…a[high]归并分类归并分类按非降次序合并两个已分类的子集●归并分类的递归算法MergeSort(low,high){if(low{mid=(low+high)/2;MergeSort(low,mid);MergeSort(mid+1,high);Merge(low,mid,high);}}●已分类子集的归并过程示例A1345691027811121314指针L=1,K=1,H=8B1指针L=2,H=8,K=2B12指针L=2,H=9,K=3B123456指针L=5,H=9,K=7B12345678指针L=5,H=11,K=9B12345678910指针L=8,H=11,K=11B1234567891011121314指针L=8,H=15,K=15Merge(low,mid,high){ElemTypeb[n];l=low;h=mid+1;k=l;while((l<=mid)&&(h<=high))/*部分合并*/{if(a[l]<=a[h])b[k++]=a[l++];elseb[k++]=a[h++];}if(l>mid)while(h<=high)b[k++]=a[h++];/*转储余下部分*/elsewhile(l<=mid)b[k++]=a[l++];a[low:high]=b[low:high];/*将b数组转储到a*/}●时间复杂度设归并分类的时间复杂度为T(n),存在递归关系:●缺点与改进方法四、比较为基础的分类算法的时间下界结论:以比较为基础的分类算法在最坏情况下的时间下界为O(nlogn),是最坏情况下的最优算法.五、快速分类●原理a[1]…a[j-1]a[j]a[j+1]…a[n]使a[1:j-1]≤a[j]a[j]使a[j+1:n]≥a[j]对a[1:j-1]快速分类a[j]对a[j+1:n]快速分类已分类的集合●实现部分分类的划分过程举例原始41362578指针r=4jk一次循环r=4jkr=41326578二次循环kj交换位置213r=46578k●实现部分分类的划分算法Partition(p,q){r=a[p];j=p+1;k=q;while(1){while((j<=k)&&(a[j]<=r))j++;while((j<=k)&&(a[k]>=r))k--;if(jelsebreak;}a[p]=a[k];a[k]=r;returnk;}●快速分类算法QuickSort(p,q){if(p{j=Partition(p,q);QuickSort(p,j-1);QuickSort(j+1,q);}}●时间复杂度快速分类算法的计算时间C(n)取决于Partition的元素比较次数.在最坏情况下(划分元素取第一个元素),每级Partition(p,q)调用,最多作p-q+1次元素比较,因此,Cw(n)=n+n-1+…+2=O(n2).在平均情况下,假设:n个元素各不相同,划分元素随机选取,取第k(1≤k≤n)个元素是等概率的,因此,存在下列递归关系:(1)(2)用n-1替换(2)中的n,得:(3)(2)-(3)得:nCA(n)-(n-1)CA(n-1)=2n+2CA(n-1)即:CA(n)/(n+1)=CA(n-1)/n+2/(n+1)(4)反复用(4)替换CA(n-1),CA(n-2),…,得到:CA(n)/(n+1)=CA(1)/2+
a[k+1]=a[k];
a[k+1]=unsorted;
考虑内层for循环中元素比较的次数T(n):
最坏情况T(n)=
=1+2+…n-1=
=O(n2)
最好情况T(n)=O(n)
三、归并分类
a[low]
a[
]
a[high]
归并分类
按非降次序合并两个已分类的子集
●归并分类的递归算法
MergeSort(low,high)
{if(low{mid=(low+high)/2;MergeSort(low,mid);MergeSort(mid+1,high);Merge(low,mid,high);}}●已分类子集的归并过程示例A1345691027811121314指针L=1,K=1,H=8B1指针L=2,H=8,K=2B12指针L=2,H=9,K=3B123456指针L=5,H=9,K=7B12345678指针L=5,H=11,K=9B12345678910指针L=8,H=11,K=11B1234567891011121314指针L=8,H=15,K=15Merge(low,mid,high){ElemTypeb[n];l=low;h=mid+1;k=l;while((l<=mid)&&(h<=high))/*部分合并*/{if(a[l]<=a[h])b[k++]=a[l++];elseb[k++]=a[h++];}if(l>mid)while(h<=high)b[k++]=a[h++];/*转储余下部分*/elsewhile(l<=mid)b[k++]=a[l++];a[low:high]=b[low:high];/*将b数组转储到a*/}●时间复杂度设归并分类的时间复杂度为T(n),存在递归关系:●缺点与改进方法四、比较为基础的分类算法的时间下界结论:以比较为基础的分类算法在最坏情况下的时间下界为O(nlogn),是最坏情况下的最优算法.五、快速分类●原理a[1]…a[j-1]a[j]a[j+1]…a[n]使a[1:j-1]≤a[j]a[j]使a[j+1:n]≥a[j]对a[1:j-1]快速分类a[j]对a[j+1:n]快速分类已分类的集合●实现部分分类的划分过程举例原始41362578指针r=4jk一次循环r=4jkr=41326578二次循环kj交换位置213r=46578k●实现部分分类的划分算法Partition(p,q){r=a[p];j=p+1;k=q;while(1){while((j<=k)&&(a[j]<=r))j++;while((j<=k)&&(a[k]>=r))k--;if(jelsebreak;}a[p]=a[k];a[k]=r;returnk;}●快速分类算法QuickSort(p,q){if(p{j=Partition(p,q);QuickSort(p,j-1);QuickSort(j+1,q);}}●时间复杂度快速分类算法的计算时间C(n)取决于Partition的元素比较次数.在最坏情况下(划分元素取第一个元素),每级Partition(p,q)调用,最多作p-q+1次元素比较,因此,Cw(n)=n+n-1+…+2=O(n2).在平均情况下,假设:n个元素各不相同,划分元素随机选取,取第k(1≤k≤n)个元素是等概率的,因此,存在下列递归关系:(1)(2)用n-1替换(2)中的n,得:(3)(2)-(3)得:nCA(n)-(n-1)CA(n-1)=2n+2CA(n-1)即:CA(n)/(n+1)=CA(n-1)/n+2/(n+1)(4)反复用(4)替换CA(n-1),CA(n-2),…,得到:CA(n)/(n+1)=CA(1)/2+
{mid=(low+high)/2;MergeSort(low,mid);MergeSort(mid+1,high);
Merge(low,mid,high);
●已分类子集的归并过程示例
A
1
3
4
5
6
9
10
2
7
8
11
12
13
14
指针
L=1,K=1,H=8
B
L=2,H=8,K=2
L=2,H=9,K=3
L=5,H=9,K=7
L=5,H=11,K=9
L=8,H=11,K=11
L=8,H=15,K=15
Merge(low,mid,high)
{ElemTypeb[n];l=low;h=mid+1;k=l;
while((l<=mid)&&(h<=high))/*部分合并*/
{if(a[l]<=a[h])b[k++]=a[l++];
elseb[k++]=a[h++];
if(l>mid)while(h<=high)b[k++]=a[h++];/*转储余下部分*/
elsewhile(l<=mid)b[k++]=a[l++];
a[low:
high]=b[low:
high];/*将b数组转储到a*/
设归并分类的时间复杂度为T(n),存在递归关系:
●缺点与改进方法
四、比较为基础的分类算法的时间下界
结论:
以比较为基础的分类算法在最坏情况下的时间下界为O(nlogn),是最坏情况下的最优算法.
五、快速分类
使a[1:
j-1]≤a[j]
使a[j+1:
n]≥a[j]
对a[1:
j-1]快速分类
对a[j+1:
n]快速分类
已分类的集合
●实现部分分类的划分过程举例
原始
r=4
j
k
一次循环
二次
循环
交换位置
●实现部分分类的划分算法
Partition(p,q)
{r=a[p];j=p+1;k=q;
while
{while((j<=k)&&(a[j]<=r))j++;
while((j<=k)&&(a[k]>=r))k--;
if(jelsebreak;}a[p]=a[k];a[k]=r;returnk;}●快速分类算法QuickSort(p,q){if(p{j=Partition(p,q);QuickSort(p,j-1);QuickSort(j+1,q);}}●时间复杂度快速分类算法的计算时间C(n)取决于Partition的元素比较次数.在最坏情况下(划分元素取第一个元素),每级Partition(p,q)调用,最多作p-q+1次元素比较,因此,Cw(n)=n+n-1+…+2=O(n2).在平均情况下,假设:n个元素各不相同,划分元素随机选取,取第k(1≤k≤n)个元素是等概率的,因此,存在下列递归关系:(1)(2)用n-1替换(2)中的n,得:(3)(2)-(3)得:nCA(n)-(n-1)CA(n-1)=2n+2CA(n-1)即:CA(n)/(n+1)=CA(n-1)/n+2/(n+1)(4)反复用(4)替换CA(n-1),CA(n-2),…,得到:CA(n)/(n+1)=CA(1)/2+
elsebreak;
a[p]=a[k];a[k]=r;
returnk;
●快速分类算法
QuickSort(p,q)
{if(p{j=Partition(p,q);QuickSort(p,j-1);QuickSort(j+1,q);}}●时间复杂度快速分类算法的计算时间C(n)取决于Partition的元素比较次数.在最坏情况下(划分元素取第一个元素),每级Partition(p,q)调用,最多作p-q+1次元素比较,因此,Cw(n)=n+n-1+…+2=O(n2).在平均情况下,假设:n个元素各不相同,划分元素随机选取,取第k(1≤k≤n)个元素是等概率的,因此,存在下列递归关系:(1)(2)用n-1替换(2)中的n,得:(3)(2)-(3)得:nCA(n)-(n-1)CA(n-1)=2n+2CA(n-1)即:CA(n)/(n+1)=CA(n-1)/n+2/(n+1)(4)反复用(4)替换CA(n-1),CA(n-2),…,得到:CA(n)/(n+1)=CA(1)/2+
{j=Partition(p,q);QuickSort(p,j-1);QuickSort(j+1,q);}}●时间复杂度快速分类算法的计算时间C(n)取决于Partition的元素比较次数.在最坏情况下(划分元素取第一个元素),每级Partition(p,q)调用,最多作p-q+1次元素比较,因此,Cw(n)=n+n-1+…+2=O(n2).在平均情况下,假设:n个元素各不相同,划分元素随机选取,取第k(1≤k≤n)个元素是等概率的,因此,存在下列递归关系:(1)(2)用n-1替换(2)中的n,得:(3)(2)-(3)得:nCA(n)-(n-1)CA(n-1)=2n+2CA(n-1)即:CA(n)/(n+1)=CA(n-1)/n+2/(n+1)(4)反复用(4)替换CA(n-1),CA(n-2),…,得到:CA(n)/(n+1)=CA(1)/2+
{j=Partition(p,q);
QuickSort(p,j-1);
QuickSort(j+1,q);
快速分类算法的计算时间C(n)取决于Partition的元素比较次数.
在最坏情况下(划分元素取第一个元素),每级Partition(p,q)调用,最多作p-q+1次元素比较,因此,Cw(n)=n+n-1+…+2=O(n2).
在平均情况下,假设:
n个元素各不相同,划分元素随机选取,取第k(1≤k≤n)个元素是等概率的,因此,存在下列递归关系:
(2)
用n-1替换
(2)中的n,得:
(3)
(2)-(3)得:
nCA(n)-(n-1)CA(n-1)=2n+2CA(n-1)
即:
CA(n)/(n+1)=CA(n-1)/n+2/(n+1)(4)
反复用(4)替换CA(n-1),CA(n-2),…,得到:
CA(n)/(n+1)=CA
(1)/2+
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1