欢迎来到冰豆网! | 帮助中心 分享价值,成长自我!
冰豆网
全部分类
  • IT计算机>
  • 经管营销>
  • 医药卫生>
  • 自然科学>
  • 农林牧渔>
  • 人文社科>
  • 工程科技>
  • PPT模板>
  • 求职职场>
  • 解决方案>
  • 总结汇报>
  • 党团工作>
  • ImageVerifierCode 换一换
    首页 冰豆网 > 资源分类 > DOCX文档下载
    分享到微信 分享到微博 分享到QQ空间

    排序算法.docx

    • 资源ID:10468849       资源大小:24.17KB        全文页数:20页
    • 资源格式: DOCX        下载积分:15金币
    快捷下载 游客一键下载
    账号登录下载
    微信登录下载
    三方登录下载: 微信开放平台登录 QQ登录
    二维码
    微信扫一扫登录
    下载资源需要15金币
    邮箱/手机:
    温馨提示:
    快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。
    如填写123,账号就是123,密码也是123。
    支付方式: 支付宝    微信支付   
    验证码:   换一换

    加入VIP,免费下载
     
    账号:
    密码:
    验证码:   换一换
      忘记密码?
        
    友情提示
    2、PDF文件下载后,可能会被浏览器默认打开,此种情况可以点击浏览器菜单,保存网页到桌面,就可以正常下载了。
    3、本站不支持迅雷下载,请使用电脑自带的IE浏览器,或者360浏览器、谷歌浏览器下载即可。
    4、本站资源下载后的文档和图纸-无水印,预览文档经过压缩,下载后原文更清晰。
    5、试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。

    排序算法.docx

    1、排序算法一、选择排序法1. 基本思想:每一趟从待排序的数据元素中选出最小(或最大)的一个元素,顺序放在已排好序的数列的最后,直到全部待排序的数据元素排完。2. 排序过程:【示例】: 初始关键字 49 38 65 97 76 13 27 49第一趟排序后 13 38 65 97 76 49 27 49第二趟排序后 13 27 65 97 76 49 38 49第三趟排序后 13 27 38 97 76 49 65 49第四趟排序后 13 27 38 49 49 97 65 76第五趟排序后 13 27 38 49 49 97 97 76第六趟排序后 13 27 38 49 49 76 76 97

    2、第七趟排序后 13 27 38 49 49 76 76 97最后排序结果 13 27 38 49 49 76 76 973.void selectionSort(Type* arr,long len) long i=0,j=0;/*iterator value*/ long maxPos; assertF(arr!=NULL,In InsertSort sort,arr is NULLn); for(i=len-1;i=1;i-) maxPos=i; for(j=0;ji;j+) if(arrmaxPosarrj)maxPos=j; if(maxPos!=i)swapArrData(arr,m

    3、axPos,i); 选择排序法的第一层循环从起始元素开始选到倒数第二个元素,主要是在每次进入的第二层循环之前,将外层循环的下标赋值给临时变量,接下来的第二层循环中,如果发现有比这个最小位置处的元素更小的元素,则将那个更小的元素的下标赋给临时变量,最后,在二层循环退出后,如果临时变量改变,则说明,有比当前外层循环位置更小的元素,需要将这两个元素交换.二.直接插入排序插入排序(Insertion Sort)的基本思想是:每次将一个待排序的记录,按其关键字大小插入到前面已经排好序的子文件中的适当位置,直到全部记录插入完成为止。直接插入排序直接插入排序(Straight Insertion Sort)

    4、:将一个记录插入到排好序的有序表中,从而得到一个新的、记录数增1的有序表。直接插入排序算法 哨兵(监视哨)有两个作用:一是作为临变量存放Ri(当前要进行比较的关键字)的副本;二是在查找循环中用来监视下标变量j是否越界。当文件的初始状态不同时,直接插入排序所耗费的时间是有很大差异的。最好情况是文件初态为正序,此时算法的时间复杂度为O(n),最坏情况是文件初态为反序,相应的时间复杂度为O(n2),算法的平均时间复杂度是O(n2)。算法的辅助空间复杂度是O(1),是一个就地排序。直接插入排序是稳定的排序方法。三. 冒泡排序算法思想:将被排序的记录数组R1.n垂直排列,每个记录Ri看作是重量为Ri.k

    5、ey的气泡。根据轻气泡不能在重气泡之下的原则,从下往上扫描数组R:凡扫描到违反本原则的轻气泡,就使其向上飘浮。如此反复进行,直到最后任何两个气泡都是轻者在上,重者在下为止。 算法: void BubbleSort(SeqList R) /R(l.n)是待排序的文件,采用自下向上扫描,对R做冒泡排序 int i,j; Boolean exchange; /交换标志 for(i=1;i=i;j-) /对当前无序区Ri.n自下向上扫描 if(Rj+1.keyRj.key)/交换记录 R0=Rj+1; /R0不是哨兵,仅做暂存单元 Rj+1=Rj; Rj=R0; exchange=TRUE; /发生了

    6、交换,故将交换标志置为真 if(!exchange) return;/本趟排序未发生交换,提前终止算法 /endfor(外循环) /BubbleSort 分析:起泡排序的结束条件为:最后一趟没有进行“交换”。从起泡排序的过程可见,起泡排序是一个增加有序序列长度的过程,也是一个缩小无序序列长度的过程,每经过一趟起泡,无序序列的长度只缩小1。 算法思想:将被排序的记录数组R1.n垂直排列,每个记录Ri看作是重量为Ri.key的气泡。根据轻气泡不能在重气泡之下的原则,从下往上扫描数组R:凡扫描到违反本原则的轻气泡,就使其向上飘浮。如此反复进行,直到最后任何两个气泡都是轻者在上,重者在下为止。 算法:

    7、 void BubbleSort(SeqList R) /R(l.n)是待排序的文件,采用自下向上扫描,对R做冒泡排序 int i,j; Boolean exchange; /交换标志 for(i=1;i=i;j-) /对当前无序区Ri.n自下向上扫描 if(Rj+1.keyRj.key)/交换记录 R0=Rj+1; /R0不是哨兵,仅做暂存单元 Rj+1=Rj; Rj=R0; exchange=TRUE; /发生了交换,故将交换标志置为真 if(!exchange) return;/本趟排序未发生交换,提前终止算法 /endfor(外循环) /BubbleSort 分析:起泡排序的结束条件为

    8、:最后一趟没有进行“交换”。从起泡排序的过程可见,起泡排序是一个增加有序序列长度的过程,也是一个缩小无序序列长度的过程,每经过一趟起泡,无序序列的长度只缩小1。四. 希尔排序基本思想: 先取一个小于n的整数d1作为第一个增量,把文件的全部记录分成d1个组。所有距离为dl的倍数的记录放在同一个组中。先在各组内进行直接插人排序;然后,取第二个增量d2d1重复上述的分组和排序,直至所取的增量dt=1(dtdt-ld2d1),即所有记录放在同一组中进行直接插入排序为止。 该方法实质上是一种分组插入方法。给定实例的shell排序的排序过程 假设待排序文件有10个记录,其关键字分别是: 49,38,65,

    9、97,76,13,27,49,55,04。 增量序列的取值依次为: 5,3,1Shell排序的算法实现1 不设监视哨的算法描述void ShellPass(SeqList R,int d) /希尔排序中的一趟排序,d为当前增量 for(i=d+1;i=n;i+) /将Rd+1n分别插入各组当前的有序区 if(Ri.key0&R0.key0 do increment=increment/3+1; /求下一增量 ShellPass(R,increment); /一趟增量为increment的Shell插入排序 while(increment1) /ShellSort注意: 当增量d=1时,Shel

    10、lPass和InsertSort基本一致,只是由于没有哨兵而在内循环中增加了一个循环判定条件j0,以防下标越界。2设监视哨的shell排序算法算法分析1增量序列的选择 Shell排序的执行时间依赖于增量序列。 好的增量序列的共同特征: 最后一个增量必须为1; 应该尽量避免序列中的值(尤其是相邻的值)互为倍数的情况。 有人通过大量的实验,给出了目前较好的结果:当n较大时,比较和移动的次数约在nl.25到1.6n1.25之间。2Shell排序的时间性能优于直接插入排序 希尔排序的时间性能优于直接插入排序的原因:当文件初态基本有序时直接插入排序所需的比较和移动次数均较少。当n值较小时,n和n2的差别

    11、也较小,即直接插入排序的最好时间复杂度O(n)和最坏时间复杂度0(n2)差别不大。在希尔排序开始时增量较大,分组较多,每组的记录数目少,故各组内直接插入较快,后来增量di逐渐缩小,分组数逐渐减少,而各组的记录数目逐渐增多,但由于已经按di-1作为距离排过序,使文件较接近于有序状态,所以新的一趟排序过程也较快。 因此,希尔排序在效率上较直接插人排序有较大的改进。3稳定性 希尔排序是不稳定的。参见上述实例,该例中两个相同关键字49在排序前后的相对次序发生了变化。五. 堆排序1、 堆排序定义 n个关键字序列Kl,K2,Kn称为堆,当且仅当该序列满足如下性质(简称为堆性质): (1) kiK2i且ki

    12、K2i+1 或(2)KiK2i且kiK2i+1(1i ) 若将此序列所存储的向量R1.n看做是一棵完全二叉树的存储结构,则堆实质上是满足如下性质的完全二叉树:树中任一非叶结点的关键字均不大于(或不小于)其左右孩子(若存在)结点的关键字。【例】关键字序列(10,15,56,25,30,70)和(70,56,30,25,15,10)分别满足堆性质(1)和(2),故它们均是堆,其对应的完全二叉树分别如小根堆示例和大根堆示例所示。2、大根堆和小根堆 根结点(亦称为堆顶)的关键字是堆里所有结点关键字中最小者的堆称为小根堆。 根结点(亦称为堆顶)的关键字是堆里所有结点关键字中最大者,称为大根堆。注意: 堆

    13、中任一子树亦是堆。 以上讨论的堆实际上是二叉堆(Binary Heap),类似地可定义k叉堆。3、堆排序特点 堆排序(HeapSort)是一树形选择排序。 堆排序的特点是:在排序过程中,将Rl.n看成是一棵完全二叉树的顺序存储结构,利用完全二叉树中双亲结点和孩子结点之间的内在关系【参见二叉树的顺序存储结构】,在当前无序区中选择关键字最大(或最小)的记录。4、堆排序与直接选择排序的区别 直接选择排序中,为了从R1.n中选出关键字最小的记录,必须进行n-1次比较,然后在R2.n中选出关键字最小的记录,又需要做n-2次比较。事实上,后面的n-2次比较中,有许多比较可能在前面的n-1次比较中已经做过,

    14、但由于前一趟排序时未保留这些比较结果,所以后一趟排序时又重复执行了这些比较操作。 堆排序可通过树形结构保存部分比较结果,可减少比较次数。 5、堆排序 堆排序利用了大根堆(或小根堆)堆顶记录的关键字最大(或最小)这一特征,使得在当前无序区中选取最大(或最小)关键字的记录变得简单。(1)用大根堆排序的基本思想 先将初始文件R1.n建成一个大根堆,此堆为初始的无序区 再将关键字最大的记录R1(即堆顶)和无序区的最后一个记录Rn交换,由此得到新的无序区R1.n-1和有序区Rn,且满足R1.n-1.keysRn.key 由于交换后新的根R1可能违反堆性质,故应将当前无序区R1.n-1调整为堆。然后再次将

    15、R1.n-1中关键字最大的记录R1和该区间的最后一个记录Rn-1交换,由此得到新的无序区R1.n-2和有序区Rn-1.n,且仍满足关系R1.n-2.keysRn-1.n.keys,同样要将R1.n-2调整为堆。 直到无序区只有一个元素为止。(2)大根堆排序算法的基本操作: 初始化操作:将R1.n构造为初始堆; 每一趟排序的基本操作:将当前无序区的堆顶记录R1和该区间的最后一个记录交换,然后将新的无序区调整为堆(亦称重建堆)。注意:只需做n-1趟排序,选出较大的n-1个关键字即可以使得文件递增有序。用小根堆排序与利用大根堆类似,只不过其排序结果是递减有序的。堆排序和直接选择排序相反:在任何时刻,

    16、堆排序中无序区总是在有序区之前,且有序区是在原向量的尾部由后往前逐步扩大至整个向量为止。(3)堆排序的算法:void HeapSort(SeqIAst R) /对R1.n进行堆排序,不妨用R0做暂存单元 int i; BuildHeap(R); /将R1-n建成初始堆 for(i=n;i1;i-) /对当前无序区R1.i进行堆排序,共做n-1趟。 R0=R1;R1=Ri;Ri=R0; /将堆顶和堆中最后一个记录交换 Heapify(R,1,i-1); /将R1.i-1重新调整为堆,仅有R1可能违反堆性质 /endfor /HeapSort(4) BuildHeap和Heapify函数的实现因为

    17、构造初始堆必须使用到调整堆的操作,先讨论Heapify的实现。 Heapify函数思想方法每趟排序开始前Rl.i是以R1为根的堆,在R1与Ri交换后,新的无序区R1.i-1中只有R1的值发生了变化,故除R1可能违反堆性质外,其余任何结点为根的子树均是堆。因此,当被调整区间是Rlow.high时,只须调整以Rlow为根的树即可。筛选法调整堆 Rlow的左、右子树(若存在)均已是堆,这两棵子树的根R2low和R2low+1分别是各自子树中关键字最大的结点。若Rlow.key不小于这两个孩子结点的关键字,则Rlow未违反堆性质,以Rlow为根的树已是堆,无须调整;否则必须将Rlow和它的两个孩子结点

    18、中关键字较大者进行交换,即Rlow与Rlarge(Rlarge.key=max(R2low.key,R2low+1.key)交换。交换后又可能使结点Rlarge违反堆性质,同样由于该结点的两棵子树(若存在)仍然是堆,故可重复上述的调整过程,对以Rlarge为根的树进行调整。此过程直至当前被调整的结点已满足堆性质,或者该结点已是叶子为止。上述过程就象过筛子一样,把较小的关键字逐层筛下去,而将较大的关键字逐层选上来。因此,有人将此方法称为筛选法。BuildHeap的实现要将初始文件Rl.n调整为一个大根堆,就必须将它所对应的完全二叉树中以每一结点为根的子树都调整为堆。显然只有一个结点的树是堆,而在

    19、完全二叉树中,所有序号 的结点都是叶子,因此以这些结点为根的子树均已是堆。这样,我们只需依次将以序号为 , -1,1的结点作为根的子树都调整为堆即可。 具体算法【参见教材】。5、大根堆排序实例 对于关键字序列(42,13,24,91,23,16,05,88),在建堆过程中完全二叉树及其存储结构的变化情况参见。6、 算法分析 堆排序的时间,主要由建立初始堆和反复重建堆这两部分的时间开销构成,它们均是通过调用Heapify实现的。 堆排序的最坏时间复杂度为O(nlgn)。堆排序的平均性能较接近于最坏性能。 由于建初始堆所需的比较次数较多,所以堆排序不适宜于记录数较少的文件。 堆排序是就地排序,辅助

    20、空间为O(1), 它是不稳定的排序方法。六. 快速排序快速排序的基本思路是:首先我们选择一个中间值middle(程序中我们可使用数组中间值),把比中间值小的放在其左边,比中间值大的放在其右边。由于这个排序算法较复杂,我们先给出其进行一次排序的程序框架(从各类数据结构教材中可得):void QuickSort(int *pData, int left, int right)int i, j;int middle, iTemp;i = left;j = right;middle = pData(left + right) / 2; /求中间值dowhile (pDatai middle) & (i

    21、 middle) & (j left) /从右扫描小于中值的数j-;if (i = j) /找到了一对值/交换iTemp = pDatai;pDatai = pDataj;pDataj = iTemp;i+;j-; while (i = j) ; /如果两边扫描的下标交错,就停止(完成一次)/当左边部分有值(leftj),递归左半边if(lefti),递归右半边if(righti)QuickSort (pData,i,right);对于n个成员,快速排序法的比较次数大约为n*logn 次,交换次数大约为(n*logn)/6次。如果n为100,冒泡法需要进行4950 次比较,而快速排序法仅需要2

    22、00 次,快速排序法的效率的确很高。快速排序法的性能与中间值的选定关系密切,如果每一次选择的中间值都是最大值(或最小值),该算法的速度就会大大下降。快速排序算法最坏情况下的时间复杂度为O(n2),而平均时间复杂度为O(n*logn)。七. 合并排序說明之前所介紹的排序法都是在同一個陣列中的排序,考慮今日有兩筆或兩筆以上的資料,它可能是不同陣列中的資料,或是不同檔案中的資料,如何為它們進行排序?解法可以使用合併排序法,合併排序法基本是將兩筆已排序的資料合併並進行排序,如果所讀入的資料尚未排序,可以先利用其它的排序方式來處理這兩筆資料,然後再將排序好的這兩筆資料合併。有人問道,如果兩筆資料本身就無

    23、排序順序,何不將所有的資料讀入,再一次進行排序?排序的精神是儘量利用資料已排序的部份,來加快排序的效率,小筆資料的排序較為快速,如果小筆資料排序完成之後,再合併處理時,因為兩筆資料都有排序了,所有在合併排序時會比單純讀入所有的資料再一次排序來的有效率。那麼可不可以直接使用合併排序法本身來處理整個排序的動作?而不動用到其它的排序方式?答案是肯定的,只要將所有的數字不斷的分為兩個等分,直到最後剩一個數字為止,然後再反過來不斷的合併,就如下圖所示: 不過基本上分割又會花去額外的時間,不如使用其它較好的排序法來排序小筆資料,再使用合併排序來的有效率。下面這個程式範例,我們使用快速排序法來處理小筆資料排

    24、序,然後再使用合併排序法處理合併的動作。例子 C #include #include #include #define MAX1 10#define MAX2 10#define SWAP(x,y) int t; t = x; x = y; y = t;int partition(int, int, int);void quicksort(int, int, int);void mergesort(int, int, int, int, int);int main(void) int number1MAX1 = 0;int number2MAX1 = 0;int number3MAX1+MAX

    25、2 = 0;int i, num;srand(time(NULL);printf(排序前:);printf(nnumber1:);for(i = 0; i MAX1; i+) number1i = rand() % 100;printf(%d , number1i);printf(nnumber2:);for(i = 0; i MAX2; i+) number2i = rand() % 100;printf(%d , number2i);/ 先排序兩筆資料quicksort(number1, 0, MAX1-1);quicksort(number2, 0, MAX2-1);printf(n排序

    26、後:);printf(nnumber1:);for(i = 0; i MAX1; i+)printf(%d , number1i);printf(nnumber2:);for(i = 0; i MAX2; i+)printf(%d , number2i);/ 合併排序mergesort(number1, MAX1, number2, MAX2, number3);printf(n合併後:);for(i = 0; i MAX1+MAX2; i+)printf(%d , number3i);printf(n);return 0;int partition(int number, int left,

    27、 int right) int i, j, s;s = numberright;i = left - 1;for(j = left; j right; j+) if(numberj = s) i+;SWAP(numberi, numberj);SWAP(numberi+1, numberright);return i+1;void quicksort(int number, int left, int right) int q;if(left right) q = partition(number, left, right);quicksort(number, left, q-1);quicksort(number, q+1, right);void mergesort(int number1, int M, int number2,int N, int number3) int i = 0, j = 0, k = 0;while(i M


    注意事项

    本文(排序算法.docx)为本站会员主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(点击联系客服),我们立即给予删除!

    温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载不扣分。




    关于我们 - 网站声明 - 网站地图 - 资源地图 - 友情链接 - 网站客服 - 联系我们

    copyright@ 2008-2022 冰点文档网站版权所有

    经营许可证编号:鄂ICP备2022015515号-1

    收起
    展开