Ⅰ 什麼是(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");
}
------------------------------------------------------------------------------------------------Mr_computer
Ⅱ C語言中冒泡排序法和選擇排序法有哪些不同
不同點:
1.
冒泡排序法:一趟一趟的將兩個相鄰的數進行交換如果有10個數則需要排9躺,如果是從大到小輸出則需要每次將後一個數和前一個數進行比較將較大的數賦值給錢一個數,將較小的數賦值給後一個數,其實就是兩個數交換,那麼第一趟交換完畢後,最小的數便出現在了數組的最後面,然後進行第二趟的比較時則要對餘下的前9個數進行比較,9趟比較完成後則數組也已經排好序。
2.
選擇排序法:10個數則是需要排9次,若按降序排列,第一次比較:則是將數組的第一個元素與數組中從第二個元素開始到最後的元素進行比較找到最大的數記錄下來然後將值賦值給數組的第一個元素,然後進行第二次比較:則是將數組的第二個元素與數組中從第三個元素開始到最後的元素進行比較,找最大的數記錄下來將值賦值給數組的第二個元素,依次循環找完。
程序分析:
1.
選擇排序:
1>.對於選擇排序,首先理解排序的思想。給定一個數組,這種思想首先假定數組的首元素為最大(最小)的。此時就要利用3個變數i,j,k表示元素的下標。i表示當前,j表示找到的最大(最小)的下標,k用於存放每次循環中最大值的下標。
2>.在掌握了程序的基本思想之後,再進行排序。找到最大的下標後賦給k。找到之後判斷所假設的當前值是否為此次循環的最大值,如果不是,就交換a[k]
與當前a[i]的值,從而將數組以一定的順序排放,最後寫一個循環將結果輸出。
2.
冒泡排序:
1>.對於冒泡排序,主要採用的是相鄰數兩兩進行比較的思想。如果後一個比前一個大(小),則將其調換位置,直至所有的數都比較完。
2>.如果給定一個大小為n的數組,那麼需要比較n-1趟,每一趟比較n-1-i次
,i
表示上次循環中已經比較完的下標。寫兩個循環
判斷,如需交換則進行交換,如果不需要交換則進行下兩個數的比較,直到所有的數比較完。最後,用一個循環將排序完成後的數全部輸出。
Ⅲ c語言選擇排序法和冒泡排序法有什麼區別
先上選擇法和冒泡法:
1.選擇法
#include<stdio.h>
void
main()
{
int
i,j,min,temp;
int
a[10];
printf("請輸入十個整數:");
for(i=0;i<=9;i++)
scanf("%d",&a[i]);
for(i=0;i<9;i++)
{
min=i;
for(j=i+1;j<=9;j++)
{
if(a[min]>a[j])
{
min=j;
}
temp=a[j];
a[j]=a[min];
a[min]=temp;
}
}
for(i=0;i<=9;i++)
printf("%4d",a[i]);
}
2.冒泡法
#include<stdio.h>
void
main()
{
int
i,j,temp;
int
a[10];
printf("請輸入十個整數:");
for(i=0;i<=9;i++)
scanf("%d",&a[i]);
for(i=0;i<9;i++)
for(j=9;j>i;j--)
{
if(a[j]<a[j-1])
{
temp=a[j];
a[j]=a[j-1];
a[j-1]=temp;
}
}/*
for(j=0;j<9-i;j++)
{
if(a[j]>a[j+1])
{
temp=a[j];
a[j]=a[j+1];
a[j+1]=temp;
}
}大的氣泡往下沉,小的氣泡往上浮!!!注意:是a[j-1]還是a[j+1];
深刻了解!!!
*/
for(i=9;i>=0;i--)
printf("%4d",a[i]);
}
通過這兩個程序,可以發現他們的編程還是有些區別的,但是總結下:
相同點:
1.都要通過n-1組排出具有n個數的順序;
2.都是通過逐個相比,比出最值的;
。。。
不同點:
1.冒泡法,顧名思義就是把小的泡冒到上面,大的泡沉到下面,最值在中間和其他的值交換;
而選擇法,是假定了一個最值,所以最值和其他的值的交換就發生在假定最值的地方;
。。。
其實冒泡法和選擇法的區別不大,都是效率比較低的方法。
Ⅳ C語言中選擇排序和冒泡排序的區別是什麼哪位大俠教教小弟
是這樣的
區別主要在交換的方式上
每一輪都把最大或最小的元素篩選出來放在相應的位置上
這是相同的
但是
對於每一輪
比如第一輪
要把1~n中最大的那個放到n這個位置
冒泡法每次比較和移動相鄰的兩項
而選擇排序每次交換當前項和第n項
我把代碼寫出來你就懂了:
冒泡:
fori:=1ton-1do
if(a[i]>a[i+1])thenswap(i,i+1);
選擇:
fori:=1ton-1do
if(a[i]>a[n])thenswap(i,n);
(swap表示交換)
總的來說,兩種排序比較的次數是相同的
但交換的次數,選擇排序是更少的
雖然兩者的時間復雜度都是O(n^2)
但通常,選擇排序更快一點參考資料:http://hi..com/yukunlinykl/blog/item/56f3986e768fe5db81cb4a17.html
Ⅳ C語言中的選擇法與冒泡法有何區別,請高人指點迷津,不甚感激!
簡單區別:
選擇法: 開始往後找到後面的數中最大或者最小的數以後才交換數據 開始位置從0變到n-2的位置 僅僅交換一次 一共最多n-1次
冒泡法: 某開始往後面,與它相臨的下一個數比較,大於(從大到小 從小到大反之)就交換數據 不僅僅交換一次 可能很多次
Ⅵ C語言 冒泡排序法和選擇法的不同,本質區別
先搬書說說書上標準的說法吧,選擇排序基本思想是每一趟在n個記錄中選取關鍵字最小的記錄作為有序序列的第I個記錄,並且令I為1~n-1,進行n-1趟選擇操作。用我的話來說(把數從小到大排列)就是把數組中的第一個數和第二個數比較,若第一個數大於第二個數,則把兩個數的位置交換,然後現在這個位置的第二個數和第三個數比較;若第一個數小於第二個數的話,兩個數的位置不變,接著將第一個數和第三個數進行比較大小。全部以此類推直到第一個數和後面所有的數進行比較,然後再把數組中原來的第二個數做這個比較,一直到數組的所有數全部遍歷一次。
冒泡排序,首先涇第一個記錄的關鍵字和第二個記錄的關鍵字進行比較,若為逆序則將兩個記錄交換,然後比較第二個和第三個記錄的關鍵字,以此類推,知道第n-1個記錄和第n個記錄的關鍵字進行過比較為止。用我的話來說就是把最先前的那個數和第二個數比較,若前面比後面小,則第二個數和第三個數進行比較,一直到遍歷一次數組中所有的元素;若前面的比後面的大,則兩個交換位置,然後用現在第二個數和第三個數進行比較,一直到遍歷一次數組中所有的元素。
估計有點昏了。那就簡單點。選擇就是原來的第一個元素和後面的所有元素進行一次比較後再用原來的第二個元素和除原來第一個元素以外的所有元素進行一次比較。冒泡就是相鄰的兩個元素進行比較,一直到遍歷一次數組所有元素才結束、。 也可以這樣想,選擇排序就是每一次遍歷數組的時候都將數組元素最大或者最小的元素按數組下標的順序放入數組,然後比較這個元素後面的元素,然後再放入元素。冒泡排序可以看作是相鄰的兩個元素進行比較,小的放在前面,大的放在後面(誰放在前面看你的需求)。
Ⅶ C語言中選擇法和冒泡法排序有什麼區別(舉例詳解)
如果用一組數,按小到大
順序
排列,如果用冒泡法,
原理
是這樣的,就是把最小的數放在最後,不斷地把
底層
的較大的數冒泡升上來,
選擇法
是用一個
變數
不斷地選擇小的數,將值付給變數再通過變數付給相應位置的
數組元素
…
Ⅷ C語言中冒泡排序法和選擇法的不同是什麼本質區別是什麼
是這樣的
區別主要在交換的方式上
每一輪都把最大或最小的元素篩選出來放在相應的位置上
這是相同的
但是
對於每一輪
比如第一輪
要把1~n 中最大的那個放到n這個位置
冒泡法每次比較和移動相鄰的兩項
而選擇排序每次交換當前項和第n項
我把代碼寫出來你就懂了:
冒泡:
for i:=1 to n-1 do
if (a[i]>a[i+1]) then swap(i,i+1);
選擇:
for i:=1 to n-1 do
if (a[i]>a[n]) then swap(i,n);
(swap 表示交換)
總的來說,兩種排序比較的次數是相同的
但交換的次數,選擇排序是更少的
雖然兩者的時間復雜度都是 O(n^2)
但通常,選擇排序更快一點
Ⅸ 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語言中的起泡法和比較法有什麼不同,它們各自是怎麼樣運行的能不能舉個詳細的例子,理解不透徹。
你說的是冒泡排序和選擇排序吧?冒泡排序和選擇排序的比較次數都是O (n�0�5) ,選擇排序的交換次數是O(n) ,最好情況是,已經有序,交換0次;最壞情況是,逆序,交換n-1次。 交換次數比冒泡排序少多了,由於交換所需CPU時間比比較所需的CPU時間多,n值較小時,選擇排序比冒泡排序快。另外選擇排序的比較次數與關鍵字的初始狀態無關,選擇排序是不穩定的排序方法。冒泡排序很簡單你應該理解吧?選擇排序的示例:【示例】: 初始關鍵字 [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 [76 97 65 49 ] 第五趟排序後 13 27 38 49 49 [97 65 76] 第六趟排序後 13 27 38 49 49 65 [97 76] 第七趟排序後 13 27 38 49 49 65 76 [97] 最後排序結果 13 27 38 49 49 65 76 97 #include <stdio.h> #include <stdlib.h> #include <time.h> int main(void) { int a[10],i,j,tmp,b; srand(time(NULL)); for(i=0;i<10;i++) a[i]=rand()%100; for(i=0;i<10;i++) printf("%3d",a[i]); printf("\n"); for(i=0;i<9;i++) { tmp=i; for(j=i+1;j<10;j++) if(a[tmp]>a[j]) tmp=j; if(i!=tmp) b=a[tmp]; a[tmp]=a[i]; a[i]=b; } for(i=0;i<10;i++) printf("%3d",a[i]); printf("\n"); return 0; }