演算法之氣泡排序
技術標籤:演算法設計
1.原理:比較兩個相鄰的元素,將值大的元素交換到右邊
2.思路:依次比較相鄰的兩個數,將比較小的數放在前面,比較大的數放在後面。
(1)第一次比較:首先比較第一和第二個數,將小數放在前面,將大數放在後面。
(2)比較第2和第3個數,將小數 放在前面,大數放在後面。
…
(3)如此繼續,知道比較到最後的兩個數,將小數放在前面,大數放在後面,重複步驟,直至全部排序完成
(4)在上面一趟比較完成後,最後一個數一定是陣列中最大的一個數,所以在比較第二趟的時候,最後一個數是不參加比較的。
(5)在第二趟比較完成後,倒數第二個數也一定是陣列中倒數第二大數,所以在第三趟的比較中,最後兩個數是不參與比較的。
(6)依次類推,每一趟比較次數減少依次
例如,要排序陣列:[10,1,35,61,89,36,55]
第一趟排序:
[10,1,35,61,89,36,55]
第一次排序:10和1比較,10大於1,交換位置 [1,10,35,61,89,36,55]
第二趟排序:10和35比較,10小於35,不交換位置 [1,10,35,61,89,36,55]
第三趟排序:35和61比較,35小於61,不交換位置 [1,10,35,61,89,36,55]
第四趟排序:61和89比較,61小於89,不交換位置 [1,10,35,61,89,36,55]
第五趟排序:89和36比較,89大於36,交換位置 [1,10,35,61,36,89,55]
第六趟排序:89和55比較,89大於55,交換位置 [1,10,35,61,36,55,89]
第一趟總共進行了六次比較,排序結果:[1,10,35,61,36,55,89]
第二趟排序:
[1,10,35,61,36,55,89]
第一次排序:1和10比較,1小於10,不交換位置 [1,10,35,61,36,55,89]
第二趟排序:10和35比較,10小於35,不交換位置 [1,10,35,61,36,55,89]
第三趟排序:35和61比較,35小於61,不交換位置 [1,10,35,61,36,55,89]
第四趟排序:61和36比較,61大於36,交換位置 [1,10,35,36,61,55,89]
第五趟排序:61和55比較,61大於55,交換位置 [1,10,35,36,55,61,89]
第二趟總共進行了六次比較,排序結果:[1,10,35,36,55,61,89]
第三趟排序:
[1,10,35,36,55,61,89]
1和10比較,1小於10,不交換位置 1,10,35,36,55,61,89
第二次排序:10和35比較,10小於35,不交換位置 1,10,35,36,55,61,89
第三次排序:35和36比較,35小於36,不交換位置 1,10,35,36,55,61,89
第四次排序:36和61比較,36小於61,不交換位置 1,10,35,36,55,61,89
第三趟總共進行了4次比較,排序結果:1,10,35,36,55,61,89
到目前位置已經為有序的情形了。
所以這裡改進一下加一個判斷,如果沒有更新就說明已經排序好了。
由此可見:N個數字要排序完成,總共進行N-1趟排序,每i趟的排序次數為(N-i)次,所以可以用雙重迴圈語句,外層控制迴圈多少趟,內層控制每一趟的迴圈次數
演算法實現:
void BubbleSort(int *a, int n)
{
for (int i = 0; i < n - 1;i++)//控制躺數
{
bool m_bflag = false;
for (int j = 0; j < n - i - 1;j++)
{
if (a[j]>a[j+1])
{
m_bflag = true;
int temp = a[j];
a[j] = a[j + 1];
a[j + 1] = temp;
}
}
if (!m_bflag)
{
cout << "一共走了"<<i<<"趟外層排序." << endl;
cout << "沒有交換資料,排序完!\n";
break;
}
}
}
int main()
{
int a[11] = { 1, 11, 2, 3, 4, 5, 6, 8,7, 9, 10 };
BubbleSort(a, 11);
for (int x :a)
{
cout << x << " ";
}
cout << endl;
system("pause");
return 0;
}
結果: