上章回顾二叉树的定义树深度的定义什么样的二叉树是满二叉树中序遍历的规则常见排序算法第六章预习检查课程目标本章概述几种常见排序算法。本章目标熟悉常见的查找算法和排序算法难点快速排序算法本章结构数据结构与算法初步常见的排序算法6.1常见的排序算法冒泡排序快速排序直接插入排序希尔排序选择排序堆排序归并排序6.1.1冒泡排序算法描述设待排序记录序列中的记录个数为n一般地,第i趟起泡排序从1到n-i+1依次比较相邻两个记录的关键字,如果发生逆序,则交换之其结果是这n-i+1个记录中,关键字最大的记录被交换到第n-i+1的位置上,最多作n-1趟。6.1.1冒泡排序算法实例212525*16080123452125*49251649chang=10825*chang=10816chang=125*25214921251608496.1.1冒泡排序算法实例25*012345i=44916chang=108252125*i=54916chang=00825216.1.1冒泡排序算法实例2108254925162149252516082149252516082149252516082149252516082149252516086.1.1冒泡排序算法实现输入n个数给a[1]到a[n]forj=1ton-1fori=1ton-ja[i]a[i+1]真假a[i]a[i+1]输出a[1]到a[n]#includestdio.hmain(){inta[11],i,j,t;printf(Input10numbers:\n);for(i=1;i11;i++)scanf(%d,&a[i]);printf(\n);for(j=1;j=9;j++)for(i=1;i=10-j;i++)if(a[i]a[i+1]){t=a[i];a[i]=a[i+1];a[i+1]=t;}printf(Thesortednumbers:\n);for(i=1;i11;i++)printf(%d,a[i]);}6.1.2快速排序算法特点:快速排序是通过比较关键码、交换记录,以某个记录为界(该记录称为支点),将待排序列分成两部分一部分所有记录的关键码大于等于支点记录的关键码另一部分所有记录的关键码小于支点记录的关键码6.1.2快速排序算法描述:任取待排序记录序列中的某个记录(例如取第一个记录)作为基准(枢),按照该记录的关键字大小,将整个记录序列划分为左右两个子序列左侧子序列中所有记录的关键字都小于或等于基准记录的关键字右侧子序列中所有记录的关键字都大于基准记录的关键字基准记录则排在这两个子序列中间(这也是该记录最终应安放的位置)。然后分别对这两个子序列重复施行上述方法,直到所有的记录都排在相应位置上为止。基准记录也称为枢轴(或支点)记录。取序列第一个记录为枢轴记录,其关键字为Pivotkey指针low指向序列第一个记录位置指针high指向序列最后一个记录位置6.1.2快速排序算法实例:2108254925*16始关键字08254925*162108254925*1608254925*1608254925*1608254925*1621pivotkey一次交换二次交换三次交换high-1完成一趟排序lowhighlowlowlowlowlowhighhighhighhighhigh6.1.2快速排序算法实例:15254925*162108254925*162108完成一趟排序分别进行快速排序有序序列08254925*16216.1.2快速排序算法分析:快速排序是一个递归过程;利用序列第一个记录作为基准,将整个序列划分为左右两个子序列。只要是关键字小于基准记录关键字的记录都移到序列左侧;快速排序的趟数取决于递归树的高度。如果每次划分对一个记录定位后,该记录的左侧子序列与右侧子序列的长度相同,则下一步将是对两个长度减半的子序列进行排序,这是最理想的情况166.1.3直接插入排序算法描述:记录存放在数组R[0….n-1]中,排序过程的某一中间时刻,R被划分成两个子区间R[0…i-1]和R[i….n-1],其中:前一个子区间是已排好序的有序区;后一个子区间则是当前未排序的部分。基本操作将当前无序区的第1个记录R[i]插入到有序区R[0….i-1]中适当的位置,使R[0…i]变为新的有序区6.1.3直接插入排序操作细节:当插入第i(i≥1)个对象时,前面的r[0],r[1],…,r[i-1]已经排好序。用r[i]的关键字与r[i-1],r[i-2],…的关键字顺序进行比较(和顺序查找类似),如果小于,则将r[x]向后移动(插入位置后的记录向后顺移)找到插入位置即将r[i]插入6.1.3直接插入排序实用例子:已知待序的一组记录的初始排列为:21,25,49,25*,16,0821254925*16080123456.1.3直接插入排序实用例子:012345temp21254925*160825i=1012345temp21254925*160849i=221254925*1608012345i=325*6.1.3直接插入排序实用例子:012345temp21254925*1608i=416012345temp21254925*1608i=50821254925*1608012345完成6.1.3直接插入排序算法实现:voidInsertSort(intr[],intn){//假设关键字为整型,放在向量r[]中inti,j,temp;for(i=1;in;i++){temp=r[i];for(j=i;j0;j--){//从后向前顺序比较,并依次后移if(tempr[j-1])r[j]=r[j-1];elsebreak;}r[j]=temp;}}6.1.3直接插入排序算法分析:关键字比较次数和记录移动次数与记录关键字的初始排列有关。最好情况下,排序前记录已按关键字从小到大有序,每趟只需与前面有序记录序列的最后一个记录比较1次,移动2次记录,总的关键字比较次数为n-1,记录移动次数为2(n-1)在平均情况下的关键字比较次数和记录移动次数约为n2/4。直接插入排序是一种稳定的排序方法直接插入排序最大的优点是简单,在记录数较少时,是比较好的办法6.1.4希尔排序希尔排序又称缩小增量排序是1959年由D.L.Shell提出来的算法描述先取定一个小于n的整数d作为第一个增量,把表的全部记录分成d组所有距离为d1的倍数的记录放在同一组中,在各组内进行直接插入排序然后取第二个增量d2d1重复上述的分组和排序,直至增量d=1,即所有记录放在同一组中进行直接插入排序为止。6.1.4希尔排序算法特点先取定一个小于n的整数d作为第一个增量,把表的全部记录分成d组所有距离为d1的倍数的记录放在同一组中,在各组内进行直接插入排序然后取第二个增量d2d1重复上述的分组和排序,直至增量d=1,即所有记录放在同一组中进行直接插入排序为止。6.1.4希尔排序运用实例先取定一个小于n的整数d作为第一个增量,把表的全部记录分成d组所有距离为d1的倍数的记录放在同一组中,在各组内进行直接插入排序然后取第二个增量d2d1重复上述的分组和排序,直至增量d=1,即所有记录放在同一组中进行直接插入排序为止。6.1.4希尔排序算法描述首先取一个整数gapn(待排序记录数)作为间隔,将全部记录分为gap个子序列,所有距离为gap的记录放在同一个子序列中在每一个子序列中分别施行直接插入排序。然后缩小间隔gap,例如取gap=gap/2重复上述的子序列划分和排序工作,直到最后取gap=1,将所有记录放在同一个序列中排序为止。6.1.4希尔排序运用实例已知待排序的一组记录的初始排列为:21,25,49,25*,16,080123452108254925*166.1.4希尔排序运用实例T=30123452108254925*160123452108254925*16T=22108254925*162108254925*16T=12108254925*162108254925*166.1.4希尔排序算法分析开始时gap的值较大,子序列中的记录较少,排序速度较快随着排序进展,gap值逐渐变小,子序列中记录个数逐渐变多,由于前面大多数记录已基本有序,所以排序速度仍然很快Gap的取法有多种。shell提出取gap=n/2,gap=gap/2,直到gap=1。6.1.5选择排序排序过程:首先通过n-1次比较,从n个数中找出最小的,将它与第一个数交换—第一趟选择排序,结果最小的数被安置在第一个元素位置上再通过n-2次比较,从剩余的n-1个数中找出关键字次小的记录,将它与第二个数交换—第二趟选择排序重复上述过程,共经过n-1趟排序后,排序结束6.1.5选择排序排序实例:例初始:[49386597761327]kji=11349一趟:13[386597764927]i=22738二趟:1327[6597764938]三趟:132738[97764965]四趟:13273849[769765]五趟:1327384965[9776]六趟:132738496576[97]kkkkjjjjjjjjjj6.1.5选择排序算法实例:212525*16080123452125*i=1492516251608490825*4921i=2i=3081625*2521初始496.1.5选择排序算法实例:25*01234525*2516084925*492108162521最小者25*无交换最小者25无交换25211608各趟排序后的结果6.1.5选择排序算法实例:01234549160825*49210825*2521i=2时选择排序的过程ikj49250825*1621ikj492525*2516251625ikj6.1.5选择排序算法实例:49250825*1621012345ikj2116k指示当前序列中最小者6.1.5选择排序算法实现:输入n个数给a[1]到a[n]fori=1ton-1forj=i+1tona[j]a[k]真假k=j输出a[1]到a[n]k=ia[i]a[k]i!=k真假#includestdio.hmain(){inta[11],i,j,k,x;printf(Input10numbers:\n);for(i=1;i11;i++)scanf(%d,&a[i]);printf(\n);for(i=1;i10;i++){k=i;for(j=i+1;j=10;j++)if(a[j]a[k])k=j;if(i!=k){x=a[i];a[i]=a[k];a[k]=x;}}printf(Thesortednumbers:\n);for(i=1;i11;i++)printf(%d,a[i]);}各种排序算法对比分析排序法平均时间最差情形稳定度额外空间备注冒泡O(n2)O(n2)稳定O(1)n小时较好交换O(n2)O(n2)不稳定O(1)n小时较好选择O(n2)O(n2)不稳定O(1)n小时较好插入O(n2)O(n2)稳定O(1)大部分已排序时较好基数O(logRB)O(logRB)稳定O(n)B是真数(0-9),R(个十百)ShellO(nlogn)O(ns)1s2不稳定O(1)s是所选分组快速O(nlogn)O(n2)不稳定O(nlogn)n大时较好归并O(nlogn)O(nlogn)稳定O(1)n大时较好堆O(nlogn)O(nlogn)不稳定O(1)n大时较好阶段小节几种常见的排序算法冒泡排序的特点快速排序的特点,一趟排序的子过程本章总结数据结构与算法初步常见的排序算法重点讲述冒泡排序和快速排序的特,同时大概了解直接插入排序,希尔排序和选择排序的基本思路实验1题目题目:实现对数组{265,301,751,129,937,863,742,694,076,438}进行排序,用快速排序方法来实现。并列出每趟排序的结果实验目的考察快速排序算法的基本思路了解快速排序算法的每趟操作流程实验分析建立