傳統的冒泡排序算法我們應該很熟悉,主要的原理是:
1.比較相鄰的元素。如果第一個比第二個大,就交換他們兩個。
2.對每一對相鄰元素作同樣的工作,從開始第一對到結尾的最後一對。在這一點,最後的元素應該會是最大的數。
3.針對所有的元素重複以上的步驟,除了最後一個。
4.持續每次對越來越少的元素重複上面的步驟,直到沒有任何一對數字需要比較。
但是此種方法每一趟循環只能找到一個最大或者最小的值,效率低,基於這個缺點,我們可以利用在每一趟排序中進行正向
和反向兩遍冒泡的方法,一次可以得到兩個值,最大值和最小值,確定兩個值的位置這樣我們的循環次數就減少了一半。
直接上代碼吧:
void bubble_sort_test(){
int arr[] = { 5, 6, 8, 3, 9, 2, 7, 0, 4, 1 };
int sz = sizeof(arr)/sizeof(arr[0]);
for (int i = 0; i < sz/2; i++){
//正向循環 把最大這下沉到 j+1的位置
for (int j = i; j< sz - i - 1; j++){
//前一個數大於後一個 下沉
if (arr[j]>arr[j + 1]){
int tmp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = tmp;
}
}
//反向循環 把最小者上冒的i的位置。
for (int j = sz-1; j>i; j--){
// 後一個數比前一個數小 上冒
if (arr[j]<arr[j - 1]){
int tmp = arr[j];
arr[j] = arr[j - 1];
arr[j - 1] = tmp;
}
}
}
int i = 0;
for (i = 0; i < sz; i++){
printf("%d ", arr[i]);
}
}
int main(){
bubble_sort_test();
getchar();
return 0;
}
還有一種情況,如果給出的數組中已經有大量已經排序好的數據,那麼按照原始方法我們還是要跑n-1趟,這是挺浪費時間的。
於是可以這樣,我們每跑完一趟就判斷一次原數組是否有序,如果有序就結束。
所以就有了一個標誌位flag來助我們判斷。
首先來看看分析:
話不多說,代碼纔是硬道理:
void bubble_sort(int arr[], int sz)
{
int i = 0;
int j = 0;
for (i = 0; i < sz - 1; i++)
{
int flag = 1;//假定每次進入都是有序的 flag爲1;
for (j = 0; j < sz - i - 1; j++){
int tmp = 0;
if (arr[j] > arr[j + 1]){
tmp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = tmp;
flag = 0;//如果發生交換,則flag 置爲0;
}
}
if (flag == 1)//如果這趟走完,沒有發生交換,則原數組有序;
break;
}
}
如果有興趣,可以將上下兩個代碼合二爲一,就是最終我能想到的優化了。