導航:首頁 > 源碼編譯 > c語言排序演算法比較

c語言排序演算法比較

發布時間:2022-08-22 13:32:12

㈠ 基於C語言的幾種排序演算法的分析

相關知識介紹(所有定義只為幫助讀者理解相關概念,並非嚴格定義):
1、穩定排序和非穩定排序
簡單地說就是所有相等的數經過某種排序方法後,仍能保持它們在排序之前的相對次序,我們就
說這種排序方法是穩定的。反之,就是非穩定的。
比如:一組數排序前是a1,a2,a3,a4,a5,其中a2=a4,經過某種排序後為a1,a2,a4,a3,a5,
則我們說這種排序是穩定的,因為a2排序前在a4的前面,排序後它還是在a4的前面。假如變成a1,a4,
a2,a3,a5就不是穩定的了。
2、內排序和外排序
在排序過程中,所有需要排序的數都在內存,並在內存中調整它們的存儲順序,稱為內排序;
在排序過程中,只有部分數被調入內存,並藉助內存調整數在外存中的存放順序排序方法稱為外排序。
3、演算法的時間復雜度和空間復雜度
所謂演算法的時間復雜度,是指執行演算法所需要的計算工作量。
一個演算法的空間復雜度,一般是指執行這個演算法所需要的內存空間。
================================================================================
*/
/*
================================================
功能:選擇排序
輸入:數組名稱(也就是數組首地址)、數組中元素個數
================================================
*/
/*
====================================================
演算法思想簡單描述:
在要排序的一組數中,選出最小的一個數與第一個位置的數交換;
然後在剩下的數當中再找最小的與第二個位置的數交換,如此循環
到倒數第二個數和最後一個數比較為止。
選擇排序是不穩定的。演算法復雜度O(n2)--[n的平方]
=====================================================
*/
void select_sort(int *x, int n)
{
int i, j, min, t;
for (i=0; i<n-1; i++) /*要選擇的次數:0~n-2共n-1次*/
{
min = i; /*假設當前下標為i的數最小,比較後再調整*/
for (j=i+1; j<n; j++)/*循環找出最小的數的下標是哪個*/
{
if (*(x+j) < *(x+min))
{
min = j; /*如果後面的數比前面的小,則記下它的下標*/
}
}
if (min != i) /*如果min在循環中改變了,就需要交換數據*/
{
t = *(x+i);
*(x+i) = *(x+min);
*(x+min) = t;
}
}
}

/*
================================================
功能:直接插入排序
輸入:數組名稱(也就是數組首地址)、數組中元素個數
================================================
*/
/*
====================================================
演算法思想簡單描述:
在要排序的一組數中,假設前面(n-1) [n>=2] 個數已經是排
好順序的,現在要把第n個數插到前面的有序數中,使得這n個數
也是排好順序的。如此反復循環,直到全部排好順序。
直接插入排序是穩定的。演算法時間復雜度O(n2)--[n的平方]
=====================================================
*/
void insert_sort(int *x, int n)
{
int i, j, t;
for (i=1; i<n; i++) /*要選擇的次數:1~n-1共n-1次*/
{
/*
暫存下標為i的數。注意:下標從1開始,原因就是開始時
第一個數即下標為0的數,前面沒有任何數,單單一個,認為
它是排好順序的。
*/
t=*(x+i);
for (j=i-1; j>=0 && t<*(x+j); j--) /*注意:j=i-1,j--,這里就是下標為i的數,在它前面有序列中找插入位置。*/
{
*(x+j+1) = *(x+j); /*如果滿足條件就往後挪。最壞的情況就是t比下標為0的數都小,它要放在最前面,j==-1,退出循環*/
}
*(x+j+1) = t; /*找到下標為i的數的放置位置*/
}
}

/*
================================================
功能:冒泡排序
輸入:數組名稱(也就是數組首地址)、數組中元素個數
================================================
*/
/*
====================================================
演算法思想簡單描述:
在要排序的一組數中,對當前還未排好序的范圍內的全部數,自上
而下對相鄰的兩個數依次進行比較和調整,讓較大的數往下沉,較
小的往上冒。即:每當兩相鄰的數比較後發現它們的排序與排序要
求相反時,就將它們互換。
下面是一種改進的冒泡演算法,它記錄了每一遍掃描後最後下沉數的
位置k,這樣可以減少外層循環掃描的次數。
冒泡排序是穩定的。演算法時間復雜度O(n2)--[n的平方]
=====================================================
*/
void bubble_sort(int *x, int n)
{
int j, k, h, t;
for (h=n-1; h>0; h=k) /*循環到沒有比較范圍*/
{
for (j=0, k=0; j<h; j++) /*每次預置k=0,循環掃描後更新k*/
{
if (*(x+j) > *(x+j+1)) /*大的放在後面,小的放到前面*/
{
t = *(x+j);
*(x+j) = *(x+j+1);
*(x+j+1) = t; /*完成交換*/
k = j; /*保存最後下沉的位置。這樣k後面的都是排序排好了的。*/
}
}
}
}

/*
================================================
功能:希爾排序
輸入:數組名稱(也就是數組首地址)、數組中元素個數
================================================
*/
/*
====================================================
演算法思想簡單描述:
在直接插入排序演算法中,每次插入一個數,使有序序列只增加1個節點,
並且對插入下一個數沒有提供任何幫助。如果比較相隔較遠距離(稱為
增量)的數,使得數移動時能跨過多個元素,則進行一次比較就可能消除
多個元素交換。D.L.shell於1959年在以他名字命名的排序演算法中實現
了這一思想。演算法先將要排序的一組數按某個增量d分成若干組,每組中
記錄的下標相差d.對每組中全部元素進行排序,然後再用一個較小的增量
對它進行,在每組中再進行排序。當增量減到1時,整個要排序的數被分成
一組,排序完成。
下面的函數是一個希爾排序演算法的一個實現,初次取序列的一半為增量,
以後每次減半,直到增量為1。
希爾排序是不穩定的。
=====================================================
*/
void shell_sort(int *x, int n)
{
int h, j, k, t;
for (h=n/2; h>0; h=h/2) /*控制增量*/
{
for (j=h; j<n; j++) /*這個實際上就是上面的直接插入排序*/
{
t = *(x+j);
for (k=j-h; (k>=0 && t<*(x+k)); k-=h)
{
*(x+k+h) = *(x+k);
}
*(x+k+h) = t;
}
}
}

/*
================================================
功能:快速排序
輸入:數組名稱(也就是數組首地址)、數組中起止元素的下標
================================================
*/
/*
====================================================
演算法思想簡單描述:
快速排序是對冒泡排序的一種本質改進。它的基本思想是通過一趟
掃描後,使得排序序列的長度能大幅度地減少。在冒泡排序中,一次
掃描只能確保最大數值的數移到正確位置,而待排序序列的長度可能只
減少1。快速排序通過一趟掃描,就能確保某個數(以它為基準點吧)
的左邊各數都比它小,右邊各數都比它大。然後又用同樣的方法處理
它左右兩邊的數,直到基準點的左右只有一個元素為止。它是由
C.A.R.Hoare於1962年提出的。
顯然快速排序可以用遞歸實現,當然也可以用棧化解遞歸實現。下面的
函數是用遞歸實現的,有興趣的朋友可以改成非遞歸的。
快速排序是不穩定的。最理想情況演算法時間復雜度O(nlog2n),最壞O(n2)
=====================================================
*/
void quick_sort(int *x, int low, int high)
{
int i, j, t;
if (low < high) /*要排序的元素起止下標,保證小的放在左邊,大的放在右邊。這里以下標為low的元素為基準點*/
{
i = low;
j = high;
t = *(x+low); /*暫存基準點的數*/
while (i<j) /*循環掃描*/
{
while (i<j && *(x+j)>t) /*在右邊的只要比基準點大仍放在右邊*/
{
j--; /*前移一個位置*/
}
if (i<j)
{
*(x+i) = *(x+j); /*上面的循環退出:即出現比基準點小的數,替換基準點的數*/
i++; /*後移一個位置,並以此為基準點*/
}
while (i<j && *(x+i)<=t) /*在左邊的只要小於等於基準點仍放在左邊*/
{
i++; /*後移一個位置*/
}
if (i<j)
{
*(x+j) = *(x+i); /*上面的循環退出:即出現比基準點大的數,放到右邊*/
j--; /*前移一個位置*/
}
}
*(x+i) = t; /*一遍掃描完後,放到適當位置*/
quick_sort(x,low,i-1); /*對基準點左邊的數再執行快速排序*/
quick_sort(x,i+1,high); /*對基準點右邊的數再執行快速排序*/
}
}

/*
================================================
功能:堆排序
輸入:數組名稱(也就是數組首地址)、數組中元素個數
================================================
*/
/*
====================================================
演算法思想簡單描述:
堆排序是一種樹形選擇排序,是對直接選擇排序的有效改進。
堆的定義如下:具有n個元素的序列(h1,h2,...,hn),當且僅當
滿足(hi>=h2i,hi>=2i+1)或(hi<=h2i,hi<=2i+1)(i=1,2,...,n/2)
時稱之為堆。在這里只討論滿足前者條件的堆。
由堆的定義可以看出,堆頂元素(即第一個元素)必為最大項。完全二叉樹可以
很直觀地表示堆的結構。堆頂為根,其它為左子樹、右子樹。
初始時把要排序的數的序列看作是一棵順序存儲的二叉樹,調整它們的存儲順序,
使之成為一個堆,這時堆的根節點的數最大。然後將根節點與堆的最後一個節點
交換。然後對前面(n-1)個數重新調整使之成為堆。依此類推,直到只有兩個節點
的堆,並對它們作交換,最後得到有n個節點的有序序列。
從演算法描述來看,堆排序需要兩個過程,一是建立堆,二是堆頂與堆的最後一個元素
交換位置。所以堆排序有兩個函數組成。一是建堆的滲透函數,二是反復調用滲透函數
實現排序的函數。
堆排序是不穩定的。演算法時間復雜度O(nlog2n)。
*/
/*
功能:滲透建堆
輸入:數組名稱(也就是數組首地址)、參與建堆元素的個數、從第幾個元素開始
*/
void sift(int *x, int n, int s)
{
int t, k, j;
t = *(x+s); /*暫存開始元素*/
k = s; /*開始元素下標*/
j = 2*k + 1; /*右子樹元素下標*/
while (j<n)
{
if (j<n-1 && *(x+j) < *(x+j+1))/*判斷是否滿足堆的條件:滿足就繼續下一輪比較,否則調整。*/
{
j++;
}
if (t<*(x+j)) /*調整*/
{
*(x+k) = *(x+j);
k = j; /*調整後,開始元素也隨之調整*/
j = 2*k + 1;
}
else /*沒有需要調整了,已經是個堆了,退出循環。*/
{
break;
}
}
*(x+k) = t; /*開始元素放到它正確位置*/
}

/*
功能:堆排序
輸入:數組名稱(也就是數組首地址)、數組中元素個數
*/
void heap_sort(int *x, int n)
{
int i, k, t;
int *p;
for (i=n/2-1; i>=0; i--)
{
sift(x,n,i); /*初始建堆*/
}
for (k=n-1; k>=1; k--)
{
t = *(x+0); /*堆頂放到最後*/
*(x+0) = *(x+k);
*(x+k) = t;
sift(x,k,0); /*剩下的數再建堆*/
}
}

void main()
{
#define MAX 4
int *p, i, a[MAX];
/*錄入測試數據*/
p = a;
printf("Input %d number for sorting :\n",MAX);
for (i=0; i<MAX; i++)
{
scanf("%d",p++);
}
printf("\n");
/*測試選擇排序*/

p = a;
select_sort(p,MAX);
/**/

/*測試直接插入排序*/
/*
p = a;
insert_sort(p,MAX);
*/

/*測試冒泡排序*/
/*
p = a;
insert_sort(p,MAX);
*/
/*測試快速排序*/
/*
p = a;
quick_sort(p,0,MAX-1);
*/
/*測試堆排序*/
/*
p = a;
heap_sort(p,MAX);
*/
for (p=a, i=0; i<MAX; i++)
{
printf("%d ",*p++);
}
printf("\n");
system("pause");
}

㈡ c語言的兩種排序

下面是C語言裡面常用的三種排序方法,但願對樓主有幫助,
一、冒泡法(起泡法)
演算法要求:用起泡法對10個整數按升序排序。
演算法分析:如果有n個數,則要進行n-1趟比較。在第1趟比較中要進行n-1次相鄰元素的兩兩比較,在第j趟比較中要進行n-j次兩兩比較。比較的順序從前往後,經過一趟比較後,將最值沉底(換到最後一個元素位置),最大值沉底為升序,最小值沉底為降序。
演算法源代碼:
# include <stdio.h>
main()
{
int a[10],i,j,t;
printf("Please input 10 numbers: ");
/*輸入源數據*/
for(i=0;i<10;i++)
scanf("%d",&a[i]);
/*排序*/
for(j=0;j<9;j++) /*外循環控制排序趟數,n個數排n-1趟*/
for(i=0;i<9-j;i++) /*內循環每趟比較的次數,第j趟比較n-j次*/
if(a[i]>a[i+1]) /*相鄰元素比較,逆序則交換*/
{ t=a[i];
a[i]=a[i+1];
a[i+1]=t;
}
/*輸出排序結果*/
printf("The sorted numbers: ");
for(i=0;i<10;i++)
printf("%d ",a[i]);
printf("\n");
}
演算法特點:相鄰元素兩兩比較,每趟將最值沉底即可確定一個數在結果的位置,確定元素位置的順序是從後往前,其餘元素可能作相對位置的調整。可以進行升序或降序排序。
演算法分析:定義n-1次循環,每個數字比較n-j次,比較前一個數和後一個數的大小。然後交換順序。
二、選擇法
演算法要求:用選擇法對10個整數按降序排序。
演算法分析:每趟選出一個最值和無序序列的第一個數交換,n個數共選n-1趟。第i趟假設i為最值下標,然後將最值和i+1至最後一個數比較,找出最值的下標,若最值下標不為初設值,則將最值元素和下標為i的元素交換。
演算法源代碼:
# include <stdio.h>
main()
{
int a[10],i,j,k,t,n=10;
printf("Please input 10 numbers:");
for(i=0;i<10;i++)
scanf("%d",&a[i]);
for(i=0;i<n-1;i++) /*外循環控制趟數,n個數選n-1趟*/
{
k=i; /*假設當前趟的第一個數為最值,記在k中 */
for(j=i+1;j<n;j++) /*從下一個數到最後一個數之間找最值*/
if(a[k]<a[j]) /*若其後有比最值更大的*/
k=j; /*則將其下標記在k中*/
if(k!=i) /*若k不為最初的i值,說明在其後找到比其更大的數*/
{ t=a[k]; a[k]=a[i]; a[i]=t; } /*則交換最值和當前序列的第一個數*/
}
printf("The sorted numbers: ");
for(i=0;i<10;i++)
printf("%d ",a[i]);
printf("\n");
}
演算法特點:每趟是選出一個最值確定其在結果序列中的位置,確定元素的位置是從前往後,而每趟最多進行一次交換,其餘元素的相對位置不變。可進行降序排序或升序排序。
演算法分析:定義外部n-1次循環,假設第一個為最值,放在參數中,在從下一個數以後找最值若後面有比前面假設的最值更大的就放在k中,然後在對k進行分析。若k部位最初的i值。也就是假設的i不是最值,那麼就交換最值和當前序列的第一個數
三、插入法
演算法要求:用插入排序法對10個整數進行降序排序。
演算法分析:將序列分為有序序列和無序列,依次從無序序列中取出元素值插入到有序序列的合適位置。初始是有序序列中只有第一個數,其餘n-1個數組成無序序列,則n個數需進n-1次插入。尋找在有序序列中插入位置可以從有序序列的最後一個數往前找,在未找到插入點之前可以同時向後移動元素,為插入元素准備空間。
演算法源代碼:
# include <stdio.h>
main()
{
int a[10],i,j,t;
printf("Please input 10 numbers: ");
for(i=0;i<10;i++)
scanf("%d",&a[i]);
for(i=1;i<10;i++) /*外循環控制趟數,n個數從第2個數開始到最後共進行n-1次插入*/
{
t=a[i]; /*將待插入數暫存於變數t中*/
for( j=i-1 ; j>=0 && t>a[j] ; j-- ) /*在有序序列(下標0 ~ i-1)中尋找插入位置*/
a[j+1]=a[j]; /*若未找到插入位置,則當前元素後移一個位置*/
a[j+1]=t; /*找到插入位置,完成插入*/
}
printf("The sorted numbers: ");
for(i=0;i<10;i++)
printf("%d ",a[i]);
printf("\n");
}
演算法特點:每趟從無序序列中取出第一個數插入到有序序列的合適位置,元素的最終位置在最後一趟插入後才能確定位置。也可是先用循環查找插入位置(可從前往後或從後往前),再將插入位置之後的元素(有序列中)逐個後移一個位置,最後完成插入。該演算法的特點是在尋找插入位置的同時完成元素的移動。因為元素的移動必須從後往前,則可將兩個操作結合在一起完成,提高演算法效率。仍可進行升序或降序排序。
二、下面是三種排序的概念及其優缺點

冒泡排序
已知一組無序數據a[1]、a[2]、……a[n],需將其按升序排列。首先比較a[1]與a[2]的值,若a[1]大於a[2]則交換兩者的值,否則不變。再比較a[2]與a[3]的值,若a[2]大於a[3]則交換兩者的值,否則不變。再比較a[3]與a[4],依此類推,最後比較a[n-1]與a[n]的值。這樣處理一輪後,a[n]的值一定是這組數據中最大的。再對a[1]~a[n-1]以相同方法處理一輪,則a[n-1]的值一定是a[1]~a[n-1]中最大的。再對a[1]~a[n-2]以相同方法處理一輪,依此類推。共處理n-1輪後a[1]、a[2]、……a[n]就以升序排列了。
優點:穩定,比較次數已知;
缺點:慢,每次只能移動相鄰兩個數據,移動數據的次數多。

選擇排序
已知一組無序數據a[1]、a[2]、……a[n],需將其按升序排列。首先比較a[1]與a[2]的值,若a[1]大於a[2]則交換兩者的值,否則不變。再比較a[1]與a[3]的值,若a[1]大於a[3]則交換兩者的值,否則不變。再比較a[1]與a[4],依此類推,最後比較a[1]與a[n]的值。這樣處理一輪後,a[1]的值一定是這組數據中最小的。再將a[2]與a[3]~a[n]以相同方法比較一輪,則a[2]的值一定是a[2]~a[n]中最小的。再將a[3]與a[4]~a[n]以相同方法比較一輪,依此類推。共處理n-1輪後a[1]、a[2]、……a[n]就以升序排列了。
優點:穩定,比較次數與冒泡排序一樣,數據移動次數比冒泡排序少;
缺點:相對之下還是慢。

插入排序
已知一組升序排列數據a[1]、a[2]、……a[n],一組無序數據b[1]、b[2]、……b[m],需將二者合並成一個升序數列。首先比較b[1]與a[1]的值,若b[1]大於a[1],則跳過,比較b[1]與a[2]的值,若b[1]仍然大於a[2],則繼續跳過,直到b[1]小於a數組中某一數據a[x],則將a[x]~a[n]分別向後移動一位,將b[1]插入到原來a[x]的位置這就完成了b[1]的插入。b[2]~b[m]用相同方法插入。(若無數組a,可將b[1]當作n=1的數組a)
優點:穩定,快;
缺點:比較次數不一定,比較次數越少,插入點後的數據移動越多,特別是當數據總量龐大的時候,但用鏈表可以解決這個問題。

㈢ C語言選擇法排序

#include<stdio.h>

#defineM 5

void main()

{

int b[M],i,j,t,k;

for(i=0;i<M;i++)

scanf("%d",&b[i]);

for(i=0;i<M-1;i++)

{

for(k=i,j=i+1;j<M;j++)

if(b[k]<b[j])

k=j;

if(i!=k)

{

t=b[i];

b[i]=b[k];

b[k]=t;

}

}

for(i=0;i<M;i++)

printf("%d ",b[i]);

}

錯在大括弧位置加錯了。

代碼:

#include<stdio.h>

void SelectionSort(int *num,int n)

{

int i = 0;

int min = 0;

int j = 0;

int tmp = 0;

for(i = 0;i < n-1;i++)

{

min = i;//每次講min置成無序組起始位置元素下標

for(j = i;j < n;j++)//遍歷無序組,找到最小元素。

{

if(num[min]>num[j])

{

min = j;

}

}

if(min != i)//如果最小元素不是無序組起始位置元素,則與起始元素交換位置

{

tmp = num[min];

num[min] = num[i];

num[i] = tmp;

}

}

}

(此處空一行)

int main()

{

int num[6] = {5,4,3,2,9,1};

int i = 0;

SelectionSort(num,6);//這里需要將數列元素個數傳入。有心者可用sizeof在函數內求得元素個數。

for(i = 0;i < 6;i++)

{

printf("%d ",num[i]);

}

return 0;

}

㈣ C語言選擇排序法有哪些

1、穩定排序和非穩定排序
簡單地說就是所有相等的數經過某種排序方法後,仍能保持它們在排序之前的相對次序,我
們就
說這種排序方法是穩定的。反之,就是非穩定的。
比如:一組數排序前是a1,a2,a3,a4,a5,其中a2=a4,經過某種排序後為a1,a2,a4,a3,a5,
則我們說這種排序是穩定的,因為a2排序前在a4的前面,排序後它還是在a4的前面。假如變
成a1,a4,
a2,a3,a5就不是穩定的了。
2、內排序和外排序
在排序過程中,所有需要排序的數都在內存,並在內存中調整它們的存儲順序,稱為內排序;
在排序過程中,只有部分數被調入內存,並藉助內存調整數在外存中的存放順序排序方法稱
為外排序。
3、演算法的時間復雜度和空間復雜度
所謂演算法的時間復雜度,是指執行演算法所需要的計算工作量。
一個演算法的空間復雜度,一般是指執行這個演算法所需要的內存空間。
======================================================================
==========
*/
/*
================================================
功能:選擇排序
輸入:數組名稱(也就是數組首地址)、數組中元素個數
================================================
*/
/*
====================================================
演算法思想簡單描述:
在要排序的一組數中,選出最小的一個數與第一個位置的數交換;
然後在剩下的數當中再找最小的與第二個位置的數交換,如此循環
到倒數第二個數和最後一個數比較為止。
選擇排序是不穩定的。演算法復雜度O(n2)--[n的平方]
=====================================================
*/
voidselect_sort(int*x,intn)
{
inti,j,min,t;
for(i=0;i<n-1;i++)/*要選擇的次數:0~n-2共n-1次*/
{
min=i;/*假設當前下標為i的數最小,比較後再調整*/
for(j=i+1;j<n;j++)/*循環找出最小的數的下標是哪個*/
{
if(*(x+j)<*(x+min))
{
min=j;/*如果後面的數比前面的小,則記下它的下標*/
}
}
if(min!=i)/*如果min在循環中改變了,就需要交換數據*/
{
t=*(x+i);
*(x+i)=*(x+min);
*(x+min)=t;
}
}
}
/*
================================================
功能:直接插入排序
輸入:數組名稱(也就是數組首地址)、數組中元素個數
================================================
*/
/*
====================================================
演算法思想簡單描述:
在要排序的一組數中,假設前面(n-1)[n>=2]個數已經是排
好順序的,現在要把第n個數插到前面的有序數中,使得這n個數
也是排好順序的。如此反復循環,直到全部排好順序。
直接插入排序是穩定的。演算法時間復雜度O(n2)--[n的平方]
=====================================================
*/
voidinsert_sort(int*x,intn)
{
inti,j,t;
for(i=1;i<n;i++)/*要選擇的次數:1~n-1共n-1次*/
{
/*
暫存下標為i的數。注意:下標從1開始,原因就是開始時
第一個數即下標為0的數,前面沒有任何數,單單一個,認為
它是排好順序的。
*/
t=*(x+i);
for(j=i-1;j>=0&&t<*(x+j);j--)/*注意:j=i-1,j--,這里就是下標為i的數,在它
列中找插入位置。*/
{
*(x+j+1)=*(x+j);/*如果滿足條件就往後挪。最壞的情況就是t比下標為0的數都
放在最前面,j==-1,退出循環*/
}
*(x+j+1)=t;/*找到下標為i的數的放置位置*/
}
}
/*
================================================
功能:冒泡排序
輸入:數組名稱(也就是數組首地址)、數組中元素個數
================================================
*/
/*
====================================================
演算法思想簡單描述:
在要排序的一組數中,對當前還未排好序的范圍內的全部數,自上
而下對相鄰的兩個數依次進行比較和調整,讓較大的數往下沉,較
小的往上冒。即:每當兩相鄰的數比較後發現它們的排序與排序要
求相反時,就將它們互換。
下面是一種改進的冒泡演算法,它記錄了每一遍掃描後最後下沉數的
位置k,這樣可以減少外層循環掃描的次數。
冒泡排序是穩定的。演算法時間復雜度O(n2)--[n的平方]
=====================================================
*/
voidbubble_sort(int*x,intn)
{
intj,k,h,t;
for(h=n-1;h>0;h=k)/*循環到沒有比較范圍*/
{
for(j=0,k=0;j<h;j++)/*每次預置k=0,循環掃描後更新k*/
{
if(*(x+j)>*(x+j+1))/*大的放在後面,小的放到前面*/
{
t=*(x+j);
*(x+j)=*(x+j+1);
*(x+j+1)=t;/*完成交換*/
k=j;/*保存最後下沉的位置。這樣k後面的都是排序排好了的。*/
}
}
}
}
/*
================================================
功能:希爾排序
輸入:數組名稱(也就是數組首地址)、數組中元素個數
================================================
*/
/*
====================================================
演算法思想簡單描述:
在直接插入排序演算法中,每次插入一個數,使有序序列只增加1個節點,
並且對插入下一個數沒有提供任何幫助。如果比較相隔較遠距離(稱為
增量)的數,使得數移動時能跨過多個元素,則進行一次比較就可能消除
多個元素交換。D.L.shell於1959年在以他名字命名的排序演算法中實現
了這一思想。演算法先將要排序的一組數按某個增量d分成若干組,每組中
記錄的下標相差d.對每組中全部元素進行排序,然後再用一個較小的增量
對它進行,在每組中再進行排序。當增量減到1時,整個要排序的數被分成
一組,排序完成。
下面的函數是一個希爾排序演算法的一個實現,初次取序列的一半為增量,
以後每次減半,直到增量為1。
希爾排序是不穩定的。
=====================================================
*/
voidshell_sort(int*x,intn)
{
inth,j,k,t;
for(h=n/2;h>0;h=h/2)/*控制增量*/
{
for(j=h;j<n;j++)/*這個實際上就是上面的直接插入排序*/
{
t=*(x+j);
for(k=j-h;(k>=0&&t<*(x+k));k-=h)
{
*(x+k+h)=*(x+k);
}
*(x+k+h)=t;
}
}
}
/*
================================================
功能:快速排序
輸入:數組名稱(也就是數組首地址)、數組中起止元素的下標
================================================
*/
/*
====================================================
演算法思想簡單描述:
快速排序是對冒泡排序的一種本質改進。它的基本思想是通過一趟
掃描後,使得排序序列的長度能大幅度地減少。在冒泡排序中,一次
掃描只能確保最大數值的數移到正確位置,而待排序序列的長度可能只
減少1。快速排序通過一趟掃描,就能確保某個數(以它為基準點吧)
的左邊各數都比它小,右邊各數都比它大。然後又用同樣的方法處理
它左右兩邊的數,直到基準點的左右只有一個元素為止。它是由
C.A.R.Hoare於1962年提出的。
顯然快速排序可以用遞歸實現,當然也可以用棧化解遞歸實現。下面的
函數是用遞歸實現的,有興趣的朋友可以改成非遞歸的。
快速排序是不穩定的。最理想情況演算法時間復雜度O(nlog2n),最壞O(n2)
=====================================================
*/
voidquick_sort(int*x,intlow,inthigh)
{
inti,j,t;
if(low<high)/*要排序的元素起止下標,保證小的放在左邊,大的放在右邊。這里以下標為
low的元素為基準點*/
{
i=low;
j=high;
t=*(x+low);/*暫存基準點的數*/
while(i<j)/*循環掃描*/
{
while(i<j&&*(x+j)>t)/*在右邊的只要比基準點大仍放在右邊*/
{
j--;/*前移一個位置*/
}
if(i<j)
{
*(x+i)=*(x+j);/*上面的循環退出:即出現比基準點小的數,替換基準點的數*/
i++;/*後移一個位置,並以此為基準點*/
}
while(i<j&&*(x+i)<=t)/*在左邊的只要小於等於基準點仍放在左邊*/
{
i++;/*後移一個位置*/
}
if(i<j)
{
*(x+j)=*(x+i);/*上面的循環退出:即出現比基準點大的數,放到右邊*/
j--;/*前移一個位置*/
}
}
*(x+i)=t;/*一遍掃描完後,放到適當位置*/
quick_sort(x,low,i-1); /*對基準點左邊的數再執行快速排序*/
quick_sort(x,i+1,high); /*對基準點右邊的數再執行快速排序*/
}
}
/*
================================================
功能:堆排序
輸入:數組名稱(也就是數組首地址)、數組中元素個數
================================================

㈤ c語言做各種排序演算法比較程序怎麼做

已經有時間讀啦,自己測就用大量數據排序計時(只即排序時間,別記讀取和輸出時間)啦

㈥ c語言 比較法排序區別

1、穩定排序和非穩定排序的不同

簡單地說就是所有相等的數經過某種排序方法後,仍能保持它們在排序之前的相對次序,我們就說這種排序方法是穩定的。反之,就是非穩定的。

比如:一組數排序前是a1,a2,a3,a4,a5,其中a2=a4,經過某種排序後為a1,a2,a4,a3,a5,則我們說這種排序是穩定的,因為a2排序前在a4的前面,排序後它還是在a4的前面。假如變成a1,a4,a2,a3,a5就不是穩定的了。

2、內排序和外排序的不同

在排序過程中,所有需要排序的數都在內存,並在內存中調整它們的存儲順序,稱為內排序;

在排序過程中,只有部分數被調入內存,並藉助內存調整數在外存中的存放順序排序方法稱為外排序。

3、演算法的時間復雜度和空間復雜度不同

所謂演算法的時間復雜度,是指執行演算法所需要的計算工作量。

一個演算法的空間復雜度,一般是指執行這個演算法所需要的內存空間。

㈦ c語言考試。問數組,常見的數組排序演算法有那幾種選擇一個描述過程。

有插入排序:直接插入排序、折半插入排序、希爾排序;交換排序:冒泡排序、快速排序;選擇排序:簡單選擇排序、堆排序;歸並排序;基數排序。
常用冒泡排序的基本概念是:依次比較相鄰的兩個數,將小數放在前面,大數放在後面(數組由小到大排序)。即首先比較第1個和第2個數,將小數放前,大數放後。然後比較第2個數和第3個數,將小數放前,大數放後,如此繼續,直至比較最後兩個數,將小數放前,大數放後,此時第一趟結束,在最後的數必是所有數中的最大數。重復以上過程,仍從第一對數開始比較(因為可能由於第2個數和第3個數的交換,使得第1個數不再小於第2個數),將小數放前,大數放後,一直比較到最大數前的一對相鄰數,將小數放前,大數放後,第二趟結束,在倒數第二個數中得到一個新的最大數。如此下去,直至最終完成排序。
由於在排序過程中總是小數往前放,大數往後放,相當於氣泡往上升,所以稱作冒泡排序。
用二重循環實現,外循環變數設為i,內循環變數設為j。外循環重復9次,內循環依次重復9,8,...,1次。每次進行比較的兩個元素都是與內循環j有關的,它們可以分別用a[j]和a[j+1]標識,i的值依次為1,2,...,9,對於每一個i,
j的值依次為1,2,...10-i。
代碼:
for(i=0;
i<NUM-1;
i++)
/*外循環:控制比較趟數*/
for(j=NUM-1;
j>i;
j--)
/*內循環:進行每趟比較*/
if(data[j]<data[j-1])
/*如果data[j]大於data[j-1],交換兩者的位置*/
{temp=data[j];
data[j]=data[j-1];
data[j-1]=temp;
};

㈧ c語言中排序方法

1、冒泡排序(最常用)
冒泡排序是最簡單的排序方法:原理是:從左到右,相鄰元素進行比較。每次比較一輪,就會找到序列中最大的一個或最小的一個。這個數就會從序列的最右邊冒出來。(注意每一輪都是從a[0]開始比較的)

以從小到大排序為例,第一輪比較後,所有數中最大的那個數就會浮到最右邊;第二輪比較後,所有數中第二大的那個數就會浮到倒數第二個位置……就這樣一輪一輪地比較,最後實現從小到大排序。

2、雞尾酒排序
雞尾酒排序又稱雙向冒泡排序、雞尾酒攪拌排序、攪拌排序、漣漪排序、來回排序或快樂小時排序, 是冒泡排序的一種變形。該演算法與冒泡排序的不同處在於排序時是以雙向在序列中進行排序。
原理:數組中的數字本是無規律的排放,先找到最小的數字,把他放到第一位,然後找到最大的數字放到最後一位。然後再找到第二小的數字放到第二位,再找到第二大的數字放到倒數第二位。以此類推,直到完成排序。

3、選擇排序
思路是設有10個元素a[1]-a[10],將a[1]與a[2]-a[10]比較,若a[1]比a[2]-a[10]都小,則不進行交換。若a[2]-a[10]中有一個以上比a[1]小,則將其中最大的一個與a[1]交換,此時a[1]就存放了10個數中最小的一個。同理,第二輪拿a[2]與a[3]-a[10]比較,a[2]存放a[2]-a[10]中最小的數,以此類推。

4、插入排序
插入排序是在一個已經有序的小序列的基礎上,一次插入一個元素*
一般來說,插入排序都採用in-place在數組上實現。
具體演算法描述如下:
⒈ 從第一個元素開始,該元素可以認為已經被排序
⒉ 取出下一個元素,在已經排序的元素序列中從後向前掃描
⒊ 如果該元素(已排序)大於新元素,將該元素移到下一位置
⒋ 重復步驟3,直到找到已排序的元素小於或者等於新元素的位置
⒌ 將新元素插入到下一位置中
⒍ 重復步驟2~5

㈨ 排序演算法性能比較(數據結構)C語言程序

這題你只要把每個演算法的程序代碼看一下,在計算下就行
冒泡排序:兩個循環,從1加到N,(1+N)N/2
=
500500,最壞交換情況是每次判斷都要交換,既500500*3次
選擇排序:也是兩個循環,比較次數跟冒泡排序一樣500500,但是這個只要底層循環交換,既只需1000*3
=
3000次賦值。
插入排序:循環次數一樣500500,但是這個最壞情況是每比較一次就賦值一次,既需500500次賦值
希爾排序:時間復雜度是N^1.3倍,比較次數和賦值應該是1000^1.3次方。
歸並排序和快速排序,你去查查它的時間復雜度是怎麼算,O(lgN*N),好像有系數,演算法導論那本書上有,現在不記得是多少了。
希望能幫到你,

閱讀全文

與c語言排序演算法比較相關的資料

熱點內容
伺服器的威脅性應該是什麼等級 瀏覽:827
3d列印機的演算法原理 瀏覽:481
騰訊雲通信伺服器 瀏覽:889
minecraft最可怕伺服器地址 瀏覽:274
程序員選專業有必要嗎 瀏覽:32
如何重裝rpc伺服器 瀏覽:637
程序員必備的app 瀏覽:167
電動汽車加密幣 瀏覽:962
xp支持多少層文件夾 瀏覽:650
阿里雲伺服器防禦指標 瀏覽:895
cc網路編程學習 瀏覽:460
單片機又叫微控制器對嗎 瀏覽:662
安卓軟體商店如何評分 瀏覽:657
linuxexecv 瀏覽:616
蘋果照片視頻文件夾 瀏覽:392
cdes加密解密演算法 瀏覽:752
app發版如何讓運營及時配活動 瀏覽:801
python結束界面 瀏覽:485
貴州兒童編程培訓 瀏覽:535
非對稱型密碼演算法 瀏覽:691