當前位置:偏方大全网 - 藥品查詢 - 緊急!!!!!!!有什麽排序方法?各有什麽特點?

緊急!!!!!!!有什麽排序方法?各有什麽特點?

4.1 簡單排序

1.選擇排序

選擇排序的基本思想是:

對待排序的記錄序列進行n-1遍的處理,第1遍處理是將L[1..n]中最小者與L[1]交換位置,第2遍處理是將L[2..n]中最小者與L[2]交換位置,......,第i遍處理是將L[i..n]中最小者與L[i]交換位置。這樣,經過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[i]);

writeln;

for i:=1 to n-1 do

begin

k:=i;

for j:=i+1 to n do

if a[j]<a[k] then k:=j;

if k<>i then

begin t:=a[i];a[i]:=a[k];a[k]:=t;end;

end;

write('output data:');

for i:= 1 to n do write(a[i]:6);

writeln;

end.

2.插入排序

插入排序的基本思想:經過i-1遍處理後,L[1..i-1]己排好序。第i遍處理僅將L[i]插入L[1..i-1]的適當位置p,原來p後的元素壹壹向右移動壹個位置,使得L[1..i]又是排好序的序列。

例2:輸入序列數據按非減順序輸出.

程序1:

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[i]);

writeln;

for i:=2 to n do

begin

k:=a[i];j:=i-1;

while (k<a[j]) and (j>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[i]:6);

writeln;

end.

3.冒泡排序

冒泡排序又稱交換排序其基本思想是:對待排序的記錄的關鍵字進行兩兩比較,如發現兩個

記錄是反序的,則進行交換,直到無反序的記錄為止。

例:輸入序列數據按非減順序輸出。

程序1:

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[i]);

for i:=1 to n -1 do

for j:=n downto i+1 do

if a[j-1]<a[j] then

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[i]:6);

writeln;

end.

程序2:

program mppx;

const n=7;

var a:array[1..n] of integer;

i,j,k,t:integer;

bool:boolean;

begin

write('Enter date:');

for i:= 1 to n do read(a[i]);

i:=1;bool:=true;

while (i<n) and bool do

begin

bool:=false;

for j:=n downto i+1 do

if a[j-1]<a[j] then

begin t:=a[j-1];a[j-1]:=a[j];a[j]:=t;bool:=true end;

i:=i+1;

end;

write('output data:');

for i:= 1 to n do write(a[i]:6);

writeln;

end.

程序3:

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[i]);

writeln;

k:=n;

while k>0 do

begin

j:=k-1;k:=0;

for i:=1 to j do

if a[i]>a[i+1] then

begin t:=a[i];a[i]:=a[i+1];a[i+1]:=t;k:=i;end;

end;

write('output data:');

for i:= 1 to n do write(a[i]:6);

writeln;

end.

返回

4.2快速排序

快速排序的思想是:先從數據序列中選壹個元素,並將序列中所有比該元素小的元素都放到它的右邊或左邊,再對左右兩邊分別用同樣的方法處之直到每壹個待處理的序列的長度為1, 處理結束.

例:輸入壹組數據小到大排序.

程序1:

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[i];

repeat

while (b[j]>=x) and (j>i) do j:=j-1;

if j>i then begin t1:=b[i]; b[i]:=b[j];b[j]:=t1;end;

while (b[i]<=x) and (i<j) do i:=i+1;

if i<j then begin t1:=b[j];b[j]:=b[i];b[i]:=t1; end

until i=j;

b[i]:=x;

i:=i+1;j:=j-1;

if s<j then quicksort(b,s,j);

if i<t then quicksort(b,i,t);

end;

begin

write('input data:');

for i:=1 to n do read(a[i]);

writeln;

quicksort(a,1,n);

write('output data:');

for i:=1 to n do write(a[i]:6);

writeln;

end.

程序2:

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[i];

repeat

while (b[j]>=x) and (j>i) do j:=j-1;

if j>i then begin b[i]:=b[j];i:=i+1;end;

while (b[i]<=x) and (i<j) do i:=i+1;

if i<j then begin b[j]:=b[i];j:=j-1; end

until i=j;

b[i]:=x;

i:=i+1;j:=j-1;

if s<j then quicksort(b,s,j);

if i<t then quicksort(b,i,t);

end;

begin

write('input data:');

for i:=1 to n do read(a[i]);

writeln;

quicksort(a,1,n);

write('output data:');

for i:=1 to n do write(a[i]:6);

writeln;

end.

返回

4.3希爾排序

基本思想:將整個無序序列分割成若幹小的子序列分別進行插入排序或冒泡排序。

序列分割方法:將相隔某個增量h的元素構成壹個子序列。在排序過程中,逐次減小這個增量,最後當h減到1時,進行壹次插入排序或冒泡排序,排序就完成。增量序列壹般采用:d1=n div 2 ,di=di-1 div 2 ;i=2,3,4.....其中n為待排序序列的長度。

程序1:(子序列是插入排序)

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[i]);

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[i]>t) do

begin a[i+d]:=a[i];i:=i-d;end;

a[i+d]:=t;

end;

end;

write('output data:');

for i:=1 to n do write(a[i]:6);

writeln;

end.

程序2:(子序列是冒泡排序)

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[i]);

writeln;

d:=n

while d>1 do

begin

d:=d div 2;

repeat

bool:=true;

for i:=1 to n-d do

if a[i]>a[i+d] then

begin temp:=a[i];a[i]:=a[i+d];a[i+d]:=temp; bool:=false end;

until bool;

end;

write('output data:');

for i:=1 to n do write(a[i]:6);

writeln;

end.

返回

4.4 堆排序與二叉樹排序

1.堆排序

堆:設有數據元素的集合(R1,R2,R3,...Rn)它們是壹棵順序二叉樹的結點且有

Ri<=R2i 和Ri<=R2i+1(或>=)

堆的性質:堆的根結點上的元素是堆中的最小元素,且堆的每壹條路徑上的元素都是有序的。

堆排序的思想是:

1)建初始堆(將結點[n/2],[ n/2]-1,...3,2,1分別調成堆)

2)當未排序完時

輸出堆頂元素,刪除堆頂元素,將剩余的元素重新建堆。

程序如下:

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[i];

while j<=m do

begin

if (j<m) and (a[j]>a[j+1]) then j:=j+1;

if t>a[j] then

begin a[i]:=a[j];i:=j;j:=2*i; end

else exit;

a[i]:=t;

end;

end;

begin

for i:=1 to n do read(a[i]);

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[i];

sift(a,1,i-1);

end;

writeln(a[1]:4);

end.

2.二叉樹排序

排序二叉樹:每壹個參加排列的數據對應二叉樹的壹個結點,且任壹結點如果有左(右)子樹,則左(右)子樹各結點的數據必須小(大)於該結點的數據。中序遍歷排序二叉樹即得排序結果。程序如下:

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[i],first);

hyt1(root);writeln;

end.

返回

4.5 歸並排序

歸並就是將多個有序的數列合成壹個有序的數列。將兩個有序序列合並為壹個有序序列叫二路歸並(merge).歸並排序就是n長度為1的子序列,兩兩歸並最後變為有序的序列。

1.二路歸並

例1:將有序表L1=(1,5,7),L2=(2,3,4,6,8,9,10)合並壹個有序表 L.

program gb;

const m=3;n=7;

type arrl1=array[1..m] of integer;

arrl2=array[1..n] of integer;

arrl=array[1..m+n] of integer;

var a:arrl1;

b:arrl2;

c:arrl;

i,j,k,r:integer;

begin

write('Enter l1(sorted):');

for i:=1 to m do read(a[i]);

write('Enter l2(sorted):');

for i:=1 to n do read(b[i]);

i:=1;j:=1;k:=0;

while (i<=m) and (j<=n) do

begin

k:=k+1;

if a[i]<=b[j] then begin c[k]:=a[i];i:=i+1; end

else begin c[k]:=b[j];j:=j+1;end;

end;

if i<=m then for r:=i to m do c[m+r]:=a[r];

if j<=n then for r:=j to n do c[n+r]:=b[r];

writeln('Output data:');

for i:=1 to m+n do write(c[i]:5);

writeln;

end.

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[i]<=r[j] then begin r2[k]:=r[i];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[s]:=r[s] else

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[i]);

mergesort(a,b,1,maxn);

for i:=1 to maxn do

write(b[i]:9);

writeln;

end.

返回

4.6 線形排序

以上我們討論的算法均是基於比較的排序算法,在排序算法中有基於數字本身的算法:計數、桶、基數排序。

1.計數排序

基本思想是對於序列中的每壹元素x,確定序列中小於x的元素的個數。

例:n個整數序列且每個值在[1,m],排序之。

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[i]);

for i:=1 to m do c[i]:=0;

for i:=1 to n do c[a[i]]:=c[a[i]]+1;

for i:=2 to m do c[i]:=c[i]+c[i-1];

for i:=n downto 1 do

begin

b[c[a[i]]]:=a[i];

c[a[i]]:=c[a[i]]-1;

end;

writeln('Sorted data:');

for i:= 1 to n do

write(b[i]:6);

end.

2.桶排序

桶排序的思想是若待排序的記錄的關鍵字在壹個明顯有限範圍內(整型)時,可設計有限個有序桶,每個桶裝入壹個值,順序輸出各桶的值,將得到有序的序列。

例:輸入n個0到100之間的整數,由小到大排序輸出。

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[i]:=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[i]>0 do begin write(i:6);b[i]:=b[i]-1 end;

writeln;

end.

3.基數排序

基本思想是對n個元素依次按k,k-1,...1位上的數字進行桶排序。

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[i]);

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[i])-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[i]:6);

end.

4.7各種排序算法的比較

1.穩定性比較

插入排序、冒泡排序、二叉樹排序、二路歸並排序及其他線形排序是穩定的

選擇排序、希爾排序、快速排序、堆排序是不穩定的

2.時間復雜性比較

插入排序、冒泡排序、選擇排序的時間復雜性為O(n2)

其它非線形排序的時間復雜性為O(nlog2n)

線形排序的時間復雜性為O(n);

3.輔助空間的比較

線形排序、二路歸並排序的輔助空間為O(n),其它排序的輔助空間為O(1);

4.其它比較

插入、冒泡排序的速度較慢,但參加排序的序列局部或整體有序時,這種排序能達到較快的速度。

反而在這種情況下,快速排序反而慢了。

當n較小時,對穩定性不作要求時宜用選擇排序,對穩定性有要求時宜用插入或冒泡排序。

若待排序的記錄的關鍵字在壹個明顯有限範圍內時,且空間允許是用桶排序。

當n較大時,關鍵字元素比較隨機,對穩定性沒要求宜用快速排序。

當n較大時,關鍵字元素可能出現本身是有序的,對穩定性有要求時,空間允許的情況下。

宜用歸並排序。

當n較大時,關鍵字元素可能出現本身是有序的,對穩定性沒有要求時宜用堆排序。

  • 上一篇:職業打假人維權合法化
  • 下一篇:龍羊宮是否已註冊商標?還有哪些類別可以註冊?
  • copyright 2024偏方大全网