排序(冒泡、插入、选择、快速)

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

那么我们在插入数的时候你会发现我们插入的数字为顺序的,那么我们可 以利用折半查找的方法来确定插入的位置!
★折半插入(paixu3b)
开始数据分成两部分:第1个数据有序,2~n个数据无序。用折半查找要插 入的位置。 FOR i:=2 TO n DO BEGIN k:=a[i]; l:=1; h:=i-1; {k为要插入的数,l和h为折半查找的上下界} WHILE l<=h DO BEGIN {当上界<=下界,就做} m:=(l+h) DIV 2; {取中界值的下标m} IF k<a[m] THEN h:=m-1 ELSE l:=m+1{如k<中界值,则下界=m-1,否 则上界=m+1} END; {出循环时,上界>下界} FOR j:=i-1 DOWNTO l DO a[j+1]:=a[j]; {将比k大的数据后移,腾出位置 供插入} a[l]:=k {将k插入上界位置} END;
(一)冒泡排序(paixu1.pas)
//
冒泡法:其实质是:先把数据存放在数组中,然后从第一个开始,分别与其后的数字比较将较 大的数换到后面去,然后再比较下面的两个数字,这样一轮下来我们就可以得出最大的数放 在最后,整个数组就已经按从小到大的顺序排列了。
i:=n; {从数据的最后操作起} REPEAT {用直到循环,f控制排序趟数} i:=i-1; f:=True; {每排一趟,要排序的元素少一个,因最大数已排至最后} FOR j:=1 TO i DO {用计数循环进行一趟排序} IF b[j+1]<b[j] THEN {如后一个小于前一个,就交换移前} BEGIN Swap(b[j+1],b[j]); f:=False END; {如有交换f为假,还要循环} UNTIL f; {如这趟排序中没有交换, f一直为真,排序结束} 说明:swap(I,j)交换两个数的值 利用f变量的使用来提高算法的执行效率; 冒泡法的时间复杂度为O(N2)
详细过程举例如下:

Байду номын сангаас
原序: 一: 二: 三: 四: 五: 六: 七: 八:
[26 5 37 1 61 11 59 15 48 19] [19 5 15 1 11] 26 [59 61 48 37] [11 5 15 1] 19 26 [59 61 48 37] [1 5] 11 [15] 19 26 [59 61 48 37] 1 5 11 [15] 19 26 [59 61 48 37] 1 5 11 15 19 26 [59 61 48 37] 1 5 11 15 19 26 [37 48] 59 [61] 1 5 11 15 19 26 37 48 59 [61] 1 5 11 15 19 26 37 48 59 61
★快速排序

原理:



(1)把N个数存放在数组S中,当前集合为S中所有数。 (2)把当前集合第一个数定为标准数K,把S分为两个子集,左边子集 S1为小于等于K的数,右边子集S2为大于等于K的数。这一操作是这样 完成的: (A)、设定集合第一个数作为标准数K,设定指针I、J,I指向集合第 一个数,J指向集合最后一个数; (B)、把J向左移(J:=J-1),直到找到一个S[J]<=K,则交换S[I]与 S[J]的位置,并把I后移(I:=I+1); (C)、把I向右移(I:=I+1),直到找到一个S[I]>=K,则交换S[I]与 S[J]的位置,并把J前移(J:=J-1); (D)、重复B、C直到I=J。 (3)依次把S1、S2作为当前集合,以第一个数作为标准数K,重 复第2步,直到S1、S2及其产生的子集元素个数为1。
(二)选择排序(Paixu1.pas)
//设数组中有N个数,取I=1,2,3,……N-1,每次找出后N-I+1个数字中最 大的与第I个数字交换位置
BEGIN FOR i:=1 TO n DO b[i]:=a[i]; {读入数据} Print(b); {输出无序的原始数据} FOR i:=1 TO n-1 DO BEGIN {用两重循环排序} k:=i; {用k先记下要交换的元素的坐标} FOR j:=i+1 TO n DO {用i的下一元素至n,逐一与k元素比较} IF b[k]>b[j] THEN k:=j; {用k记下较小元素的坐标} IF i<>k THEN Swap(b[i],b[k]) {把较小元素与i元素交换} END; Print(b); Readln {输出有序数据} END. 时间复杂度O(N2)
快速排序法是所有排序方法中速度最快、效率最高的方法
procedure dg(x,y:integer);{X,Y表示集合的左右边界,即把第X到第Y个数进行排序} var i,j,b,c,d,e,f,k:integer; begin k:=n[x];{标准数} i:=x;j:=y{I,J为指针} repeat var n:array[1..10] of integer; j:=j+1; a:integer; repeat {从J往左找到一个n[j]<=k} procedure dg(x,y:integer); j:=j-1; begin until (n[j]<=k) or (i>j); clrscr; if i<=j then begin for a:=1 to 10 do read(n[a]); b:=n[i]; n[i]:=n[j]; n[j]:=b; {交换} dg(1,10); i:=i+1; {左指针右移} for a:=1 to 10 do write(n[a]:4); end; end. i:=i-1; repeat {从I往右找到一个n[i]>=k} i:=i+1; until (n[i]>=k) or (i>j); if i<=j then begin b:=n[i];n[i]:=n[j]; n[j]:=b; {交换} j:=j-1; end; until i>j; if j-x>0 then dg(x,j); {如果集合中不止一个数则进入下一层递归,X,J为新边界} if y-i>0 then dg(i,y); {如果集合中不止一个数则进入下一层递归,I,Y为新边界} end;
⑴无序表从头向后搜索,有序表从后向前搜索,一一插入(简称从头插入) ⑶无序表从头向后搜索,有序表折半查找搜索,一一插入(简称折半插入)
1) 从尾插入(paixu3a)
开始数据分成两部分:第n个数据有序,1~n-1个数据无序 FOR i:=n-1 DOWNTO 1 DO BEGIN {从倒数二个到1数据一一插入} k:=a[i]; j:=i+1; {k为要插入的数,j是有序数列的最小下标} WHILE (k>a[j]) AND (j<=n) DO {当k大于此数,且有序数列后面还有 数,就} BEGIN a[j-1]:=a[j]; j:=j+1; END; {将此数前移,拿后面的数再与k比} a[j-1]:=k {当k小于等于有序数列的某数就退出当循环,将k插入此数 之前} END;
基本算法介绍(一)
---排序(冒泡、插入、选择、快速)
排序算法综述
在很多数据处理的时候都用到了排序,排序
的算法较多。现在要求熟练掌握选择排序、 冒泡排序、插入排序。他们的时间复杂度为 O(N2),如果N比较大的时候这些算法的时间复 杂度就显的比较大,我们今天要学习一种改良 后的插入法排序方法,该算法的时间复杂度为 log2N*N ,效率大大增加,另外我们要学习一种 执行效率最高的快速排序法(分治的利用)它 的时间复杂度为(log2n)2。
三)插入排序
插入法排序是把存放在数组中的未经排序的数逐个插入到另外一个数组中。 如有下列未排序的数组A的元素: 49 38 65 97 76 13 27 45 用插入方法按升序排序为: 13 27 38 45 49 65 76 97 可把数据分成两部分前面的数据有序(开始时只有第1个数据),后面的数据无序 (开始时2~n个数据无序),然后把无序的数据插入到有序的数据中去。无序 数据减少,有序数据增多。把无序数据全部插入为止, 程序分为查找插入的位置、移动数据、插入数据等。查找搜索的方法有三种:
相关文档
最新文档