完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
影响排序效果的因素
因为不同的排序方法适应不同的应用环境和要求,所以选择合适的排序方法应综合考虑下列因素: ①待排序的记录数目n; ②记录的大小(规模); ③关键字的结构及其初始状态; ④对稳定性的要求; ⑤语言工具的条件; ⑥存储结构; ⑦时间和辅助空间复杂度等。 不同条件下,排序方法的选择 排序算法的稳定性 1) 稳定的:如果存在多个具有相同排序码的记录,经过排序后,这些记录的相对次序仍然保持不变,则这种排序算法称为稳定的。 一、 简单排序 1.选择排序 选择排序的基本思想是: 对待排序的记录序列进行n-1遍的处理,第1遍处理是将L[1..n]中最小者与L[1]交换位置,第2遍处理是将L[2..n]中最小者与L[2]交换位置,......,第i遍处理是将L[i..n]中最小者与L交换位置。这样,经过i遍处理之后,前i个记录的位置就已经按从小到大的顺序排列好了。 例1:输入序列数据按非减顺序输出. 程序如下: program xzpx; const n=7; var a:array[1..n] of integer; i,j,k,t:integer; begin write('Enter date:'); for i:= 1 to n do read(a); writeln; for i:=1 to n-1 do begin k:=i; for j:=i+1 to n do if a[j][url=]if k<>i then begin t:=a;a:=a[k];a[k]:=t;end; end; write('output data:'); for i:= 1 to n do write(a:6); writeln; end.[/url] [url=]2.插入排序 插入排序的基本思想:经过i-1遍处理后,L[1..i-1]己排好序。第i遍处理仅将L插入L[1..i-1]的适当位置p,原来p后的元素一一向右移动一个位置,使得L[1..i]又是排好序的序列。[/url] [url=]例2:输入序列数据按非减顺序输出.[/url] [url=]程序1:[/url] [url=]program crpx; const n=7; var a:array[1..n] of integer; i,j,k,t:integer; begin write('Enter date:'); for i:= 1 to n do read(a); writeln; for i:=2 to n do begin k:=a;j:=i-1; while (k[/url][url=]0) do begin a[j+1]:=a[j];j:=j-1 end; a[j+1]:=k; end; write('output data:'); for i:= 1 to n do write(a:6); writeln; end.[/url] [url=]3.冒泡排序 冒泡排序又称交换排序其基本思想是:对待排序的记录的关键字进行两两比较,如发现两个[/url] [url=]记录是反序的,则进行交换,直到无反序的记录为止。[/url] [url=]例:输入序列数据按非减顺序输出。[/url] [url=]程序1:[/url] [url=]program mppx; const n=7; var a:array[1..n] of integer; i,j,k,t:integer; begin write('Enter date:'); for i:= 1 to n do read(a); for i:=1 to n -1 do for j:=n downto i+1 do if a[j-1][/url][url=]begin t:=a[j-1];a[j-1]:=a[j];a[j]:=t end; write('output data:'); for i:= 1 to n do write(a:6); writeln; end.[/url] [url=]二、快速排序[/url] [url=]快速排序的思想是:先从数据序列中选一个元素,并将序列中所有比该元素小的元素都放到它的右边或左边,再对左右两边分别用同样的方法处之直到每一个待处理的序列的长度为1, 处理结束.[/url] [url=]例:输入一组数据小到大排序.[/url] [url=]程序1:[/url] [url=]program kspv; const n=7; type arr=array[1..n] of integer; var a:arr; i:integer; procedure quicksort(var b:arr; s,t:integer); var i,j,x,t1:integer; begin i:=s;j:=t;x:=b; repeat while (b[j]>=x) and (j>i) do j:=j-1; if j>i then begin t1:=b; b:=b[j];b[j]:=t1;end; while (b<=x) and (i if i until i=j; b:=x; i:=i+1;j:=j-1; if s if i end; begin write('input data:'); for i:=1 to n do read(a); writeln; quicksort(a,1,n); write('output data:'); for i:=1 to n do write(a:6); writeln; end.[/url] [url=]程序2:[/url] [url=]program kspv; const n=7; type arr=array[1..n] of integer; var a:arr; i:integer; procedure quicksort(var b:arr; s,t:integer); var i,j,x:integer; begin i:=s;j:=t;x:=b; repeat while (b[j]>=x) and (j>i) do j:=j-1; if j>i then begin b:=b[j];i:=i+1;end; while (b<=x) and (i if i until i=j; b:=x; i:=i+1;j:=j-1; if s if i end; begin write('input data:'); for i:=1 to n do read(a); writeln; quicksort(a,1,n); write('output data:'); for i:=1 to n do write(a:6); writeln; end.[/url] [url=]三、希尔排序 [/url] [url=]基本思想:将整个无序序列分割成若干小的子序列分别进行插入排序或冒泡排序。[/url] [url=]序列分割方法:将相隔某个增量h的元素构成一个子序列。在排序过程中,逐次减小这个增量,最后当h减到1时,进行一次插入排序或冒泡排序,排序就完成。增量序列一般采用:d1=n div 2 ,di=di-1 div 2 ;i=2,3,4.....其中n为待排序序列的长度。[/url] [url=]程序1:(子序列是插入排序)[/url] [url=]program xepx; const n=7; type arr=array[1..n] of integer; var a:arr; i,j,t,d:integer; bool:boolean; begin write('input data:'); for i:=1 to n do read(a); writeln; d:=n; while d>1 do begin d:=d div 2; for j:=d+1 to n do begin t:=a[j];i:=j-d; while (i>0) and (a>t) do begin a[i+d]:=a;i:=i-d;end; a[i+d]:=t; end; end; write('output data:'); for i:=1 to n do write(a:6); writeln; end.[/url] [url=]程序2:(子序列是冒泡排序)[/url] [url=]program xepx; const n=7; type arr=array[1..n] of integer; var a:arr; i,temp,d:integer; bool:boolean; begin write('input data:'); for i:=1 to n do read(a); writeln; d:=n while d>1 do begin d:=d div 2; repeat bool:=true; for i:=1 to n-d do if a>a[i+d] then begin temp:=a;a:=a[i+d];a[i+d]:=temp; bool:=false end; until bool; end; write('output data:'); for i:=1 to n do write(a:6); writeln; end.[/url] [url=]四、堆排序与二叉树排序[/url] [url=]1.堆排序 堆:设有数据元素的集合(R1,R2,R3,...Rn)它们是一棵顺序二叉树的结点且有[/url] [url=]Ri<=R2i 和Ri<=R2i+1(或>=)[/url] [url=]堆的性质:堆的根结点上的元素是堆中的最小元素,且堆的每一条路径上的元素都是有序的。[/url] [url=]堆排序的思想是:[/url] [url=]1)建初始堆(将结点[n/2],[ n/2]-1,...3,2,1分别调成堆)[/url] [url=]2)当未排序完时[/url] [url=]输出堆顶元素,删除堆顶元素,将剩余的元素重新建堆。[/url] [url=]程序如下:[/url] [url=]program duipx; const n=8; type arr=array[1..n] of integer; var a:arr;i:integer; procedure sift(var a:arr;l,m:integer); var i,j, t:integer; begin i:=l;j:=2*i;t:=a; while j<=m do begin if (ja[j+1]) then j:=j+1; if t>a[j] then begin a:=a[j];i:=j;j:=2*i; end else exit; a:=t; end;[/url] [url=]end; begin for i:=1 to n do read(a); for i:=(n div 2) downto 1 do sift(a,i,n); for i:=n downto 2 do begin write(a[1]:4); a[1]:=a; sift(a,1,i-1); end; writeln(a[1]:4); end.[/url] [url=]2.二叉树排序 排序二叉树:每一个参加排列的数据对应二叉树的一个结点,且任一结点如果有左(右)子树,则左(右)子树各结点的数据必须小(大)于该结点的数据。中序遍历排序二叉树即得排序结果。程序如下:[/url] [url=]program pxtree; const a:array[1..8] of integer=(10,18,3,8,12,2,7,3); type point=^nod; nod=record w:integer; right,left:point ; end; var root,first:point;k:boolean;i:integer; procedure hyt(d:integer;var p:point); begin if p=nil then begin new(p); with p^ do begin w:=d;right:=nil;left:=nil end; if k then begin root:=p; k:=false end; end else with p^ do if d>=w then hyt(d,right) else hyt(d,left); end; procedure hyt1(p:point); begin with p^ do begin if left<>nil then hyt1(left); write(w:4); if right<>nil then hyt1(right); end end; begin first:=nil;k:=true; for i:=1 to 8 do hyt(a,first); hyt1(root);writeln; end.[/url] [url=]五、归并排序[/url] [url=]归并就是将多个有序的数列合成一个有序的数列。将两个有序序列合并为一个有序序列叫二路归并(merge).归并排序就是n长度为1的子序列,两两归并最后变为有序的序列。[/url] [url=]1.二路归并 例1:将有序表L1=(1,5,7),L2=(2,3,4,6,8,9,10)合并一个有序表 L.[/url] [url=]program gb;[/url] [url=]const m=3;n=7;[/url] [url=]type arrl1=array[1..m] of integer;[/url] [url=]arrl2=array[1..n] of integer;[/url] [url=]arrl=array[1..m+n] of integer;[/url] [url=]var a:arrl1;[/url] [url=]b:arrl2;[/url] [url=]c:arrl;[/url] [url=]i,j,k,r:integer;[/url] [url=]begin[/url] [url=]write('Enter l1(sorted):');[/url] [url=]for i:=1 to m do read(a);[/url] [url=]write('Enter l2(sorted):');[/url] [url=]for i:=1 to n do read(b);[/url] [url=]i:=1;j:=1;k:=0;[/url] [url=]while (i<=m) and (j<=n) do[/url] [url=]begin[/url] [url=]k:=k+1;[/url] [url=]if a<=b[j] then begin c[k]:=a;i:=i+1; end[/url] [url=]else begin c[k]:=b[j];j:=j+1;end;[/url] [url=]end;[/url] [url=]if i<=m then for r:=i to m do c[m+r]:=a[r];[/url] [url=]if j<=n then for r:=j to n do c[n+r]:=b[r];[/url] [url=]writeln('Output data:');[/url] [url=]for i:=1 to m+n do write(c:5);[/url] [url=]writeln;[/url] [url=]end.[/url] [url=]2.归并排序 program gbpx; const maxn=7; type arr=array[1..maxn] of integer; var a,b,c:arr; i:integer; procedure merge(r:arr;l,m,n:integer;var r2:arr); var i,j,k,p:integer; begin i:=l;j:=m+1;k:=l-1; while (i<=m)and (j<=n) do begin k:=k+1; if r<=r[j] then begin r2[k]:=r;i:=i+1 end else begin r2[k]:=r[j];j:=j+1 end end; if i<=m then for p:=i to m do begin k:=k+1;r2[k]:=r[p] end; if j<=n then for p:=j to n do begin k:=k+1;r2[k]:=r[p] end; end; procedure mergesort( var r,r1:arr;s,t:integer); var k:integer; c:arr; begin if s=t then r1 begin k:=(s+t) div 2; mergesort(r,c,s,k); mergesort(r,c,k+1,t); merge(c,s,k,t,r1) end; end; begin write('Enter data:'); for i:= 1 to maxn do read(a); mergesort(a,b,1,maxn); for i:=1 to maxn do write(b:9); writeln; end.[/url] [url=]六、 线形排序[/url] [url=]以上我们讨论的算法均是基于比较的排序算法,在排序算法中有基于数字本身的算法:计数、桶、基数排序。[/url] [url=]1.计数排序 基本思想是对于序列中的每一元素x,确定序列中小于x的元素的个数。[/url] [url=]例:n个整数序列且每个值在[1,m],排序之。[/url] [url=]program jspx; const m=6;n=8; var i,j:integer; a,b:array[1..n] of integer; c:array[1..m] of integer; begin writeln('Enter data:'); for i:=1 to n do read(a); for i:=1 to m do c:=0; for i:=1 to n do c[a]:=c[a]+1; for i:=2 to m do c:=c+c[i-1]; for i:=n downto 1 do begin b[c[a]]:=a; c[a]:=c[a]-1; end; writeln('Sorted data:'); for i:= 1 to n do write(b:6); end.[/url] [url=]2.桶排序 桶排序的思想是若待排序的记录的关键字在一个明显有限范围内(整型)时,可设计有限个有序桶,每个桶装入一个值,顺序输出各桶的值,将得到有序的序列。[/url] [url=]例:输入n个0到100之间的整数,由小到大排序输出。[/url] [url=]program tpx; const n=7; var b:array[0..100] of integer; k:0..100; i:integer; begin write('Enter date:(0-100)'); for i:=0 to 100 do b:=0; for i:= 1 to n do begin read(k); b[k]:=b[k]+1; end; writeln('Output data:'); for i:=0 to 100 do while b>0 do begin write(i:6);b:=b-1 end; writeln; end.[/url] [url=]3.基数排序 基本思想是对n个元素依次按k,k-1,...1位上的数字进行桶排序。[/url] [url=]program jspx; const n=8; type link=^node; node=record data:integer; next:link; end; var i,j,l,m,k:integer; a:array[1..n] of integer; s:string; q,head:array[0..9] of link; p,p1:link; begin writeln('Enter data:'); for i:=1 to n do read(a); for i:=5 downto 1 do begin for j:=0 to 9 do begin new(head[j]); head[j]^.next:=nil; q[j]:=head[j] end; for j:=1 to n do begin str(a[j],s); for k:=1 to 5-length(s) do s:='0'+ s; m:=ord(s)-48; new(p); p^.data:=a[j]; p^.next:=nil; q[m]^.next:=p; q[m]:=p; end; l:=0; for j:=0 to 9 do begin p:=head[j]; while p^.next<>nil do begin l:=l+1;p1:=p;p:=p^.next;dispose(p1);a[l]:=p^.data; end; end; end; writeln('Sorted data:'); for i:= 1 to n do write(a:6); end.[/url] [url=]七、各种排序算法的比较[/url] [url=]1.稳定性比较[/url] [url=]插入排序、冒泡排序、二叉树排序、二路归并排序及其他线形排序是稳定的[/url] [url=]选择排序、希尔排序、快速排序、堆排序是不稳定的[/url] [url=]2.时间复杂性比较[/url] [url=]插入排序、冒泡排序、选择排序的时间复杂性为O(n2)[/url] [url=]其它非线形排序的时间复杂性为O(nlog2n)[/url] [url=]线形排序的时间复杂性为O(n);[/url] [url=]3.辅助空间的比较[/url] [url=]线形排序、二路归并排序的辅助空间为O(n),其它排序的辅助空间为O(1);[/url] [url=]4.其它比较[/url] [url=]插入、冒泡排序的速度较慢,但参加排序的序列局部或整体有序时,这种排序能达到较快的速度。[/url] [url=]反而在这种情况下,快速排序反而慢了。[/url] [url=]当n较小时,对稳定性不作要求时宜用选择排序,对稳定性有要求时宜用插入或冒泡排序。[/url] [url=]若待排序的记录的关键字在一个明显有限范围内时,且空间允许是用桶排序。[/url] [url=]当n较大时,关键字元素比较随机,对稳定性没要求宜用快速排序。[/url] [url=]当n较大时,关键字元素可能出现本身是有序的,对稳定性有要求时,空间允许的情况下。[/url] [url=]宜用归并排序。[/url] [url=]当n较大时,关键字元素可能出现本身是有序的,对稳定性没有要求时宜用堆排序。[/url]
|
|
|
|
只有小组成员才能发言,加入小组>>
12135 浏览 2 评论
4470 浏览 3 评论
3703 浏览 5 评论
9539 浏览 47 评论
4510 浏览 9 评论
709浏览 0评论
510浏览 0评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-24 21:18 , Processed in 0.364856 second(s), Total 44, Slave 34 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号