在學習過程中,老師教了一個簡單的排序算法——冒泡排序。比如這麼說:混沌未開之際,盤古大神開天闢地,清而輕的上升爲天,濁而重的下沉爲地。冒泡排序就是類似把清(小)的上升,重(大)的下沉。
代碼如下:
// 冒泡排序
// param a:待排序數組
// param nTotalCount:數組長度
void sortBub(int a[], int nTotalCount)
{
int nLen = nTotalCount - 1;
for (int i = 0; i < nLen; ++i)
{
for (int j = i + 1; j <= nLen; ++j)
{
if (a[i] > a[j])
{
int temp = a[j];
a[j] = a[i];
a[i] = temp;
}
}
}
}
冒泡排序算法很容易看出有兩個for循環,故此容易得出時間複雜度爲O(n²),那麼是不是可以改進一下下呢,考慮到每排序完之後肯定是a[i]<a[i+1]的情況,並且所有的位置上的元素都比後一個元素小那麼這個排序絕對是完成狀態,那我們是不是可以考慮冒泡排序只比較相鄰兩個數據呢?一條鏈上1...n, n個數據,兩兩比較相鄰數據,並且還要有一個標誌位來特殊判斷下結束狀態,那麼代碼就呼之欲出了。
// 冒泡排序改進版
// param a:待排序數組
// param nTotalCount:數組長度
void sortBub(int a[], int nTotalCount)
{
bool flag = true; // 增加一個結束狀態判斷標誌位
for (int i = 0; i < nTotalCount && flag;++i)
{
flag = false;
for (int j = nTotalCount - 2; j >= i; --j)
{
if (a[j] > a[j + 1]) // 有可以交換位置的繼續交換位置
{
int temp = a[j];
a[j] = a[j + 1];
a[j + 1] = temp;
flag = true;
}
}
}
}
主測試代碼:
// 打印數據
void printData(const int a[], int nTotalCount)
{
int nLineSpace = 0;
for (int i = 0; i < nTotalCount; i++)
{
nLineSpace++;
cout << a[i] << ",";
if (nLineSpace == 10)
{
nLineSpace = 0;
cout << endl;
}
}
}
int main(_In_ int _Argc, _In_reads_(_Argc) _Pre_z_ char ** _Argv, _In_z_ char ** _Env)
{
const int nTotalCount = 100000;
int a[nTotalCount] = { 0 };
srand((unsigned int)(time(NULL)));
clock_t nStart, nFinish;
//*
// 隨機賦值
for_each(a, a + nTotalCount, [](int & num){num = rand(); });
// 遍歷排序
nStart = clock();
sort(a, a + nTotalCount); // 系統自帶排序
nFinish = clock();
// 打印消耗時間
cout << "sort cost time:" << nFinish - nStart << "ms." << endl;
//*/
//*
// 隨機賦值
for_each(a, a + nTotalCount, [](int & num){num = rand(); });
// 遍歷排序
nStart = clock();
sortBub(a, nTotalCount); // 冒泡排序
nFinish = clock();
// 打印消耗時間
cout << "sort cost time:" << nFinish - nStart << "ms." << endl;
//*/
// 打印信息
//printData(a, nTotalCount);
system("pause");
return 0;
}
包含的頭文件:
#include <iostream>
#include <algorithm>
#include <ctime>
using namespace std;
今後還會加入其它排序算法的比較,所以這裏預先加一個消耗時間的打印,冒泡排序先寫到這裏了,有什麼不懂或者更好的排序方法歡迎留言討論。