有了前兩篇文章的基礎(冒泡排序、插入排序的傳送門),到這裏可以加快速度,就將這三個排序算法放在了一起寫了,以免一篇文章字數過少。
1.選擇排序
在計算機科學中,選擇排序是一種排序算法,特別是就地 比較排序。它具有O(n^2)時間複雜度,使其在大型列表上效率低,並且通常比類似的插入排序更差。選擇排序因其簡單性而着稱,並且在某些情況下具有優於更復雜算法的性能優勢,特別是在輔助存儲器有限的情況下。
該算法將輸入列表分爲兩部分:已經排序的項目子列表,在列表的前面(左側)從左到右構建,以及剩餘要排序的項目的子列表佔用其餘部分。名單。最初,排序的子列表爲空,未排序的子列表是整個輸入列表。該算法通過查找未排序子列表中的最小(或最大,取決於排序順序)元素,與最左邊的未排序元素(將其按排序順序)交換(交換),並將子列表邊界向右移動一個元素來繼續。
具體實現代碼如下:
void Bubble::goChoice()
{
for (int i = 0;i < length; i++) { //先進行整體循環遍歷
int index = i; //當前比較的位子
for (int j = i+1;j < length; j++) {
if(data[index] > data[j]){ //在餘下的數找到其最小的數
index = j;
bubbleSignal(j);
QThread::msleep(static_cast<unsigned int>(mDelay));
}
}
if(index == i) //沒有找到,即表示當前數是餘下數的最小數
continue;
else { //找到,即將當前位子的數與找到的數進行交換
int temp = data[index];
data[index] = data[i];
data[i] = temp;
}
bubbleSignal(i);
QThread::msleep(static_cast<unsigned int>(mDelay));
}
for(int i = 0; i < length;i++){
bubbleSignal(i);
QThread::msleep(static_cast<unsigned int>(mDelay));
}
}
運行結果
2.堆排序
Wiki介紹:
在計算機科學中,heapsort是一種基於比較的 排序算法。Heapsort可以被認爲是一種改進的選擇排序:像該算法一樣,它將輸入分爲排序區域和未排序區域,並通過提取最大元素並將其移動到排序區域來迭代縮小未排序區域。改進包括使用堆數據結構而不是線性時間搜索來找到最大值。[1]
儘管在大多數機器上實際上比實施良好的快速排序有些慢,但它具有更有利的最壞情況O(n log n)運行時間的優點。Heapsort是一種就地算法,但它不是一個穩定的類型。
基本思想是:
將待排序的序列構造成一個大頂堆。此時,整個序列的最大值就是堆頂的根結點。將它與堆數組的末尾元素進行交換,此時末尾元素就是最大值,然後將剩餘的前n-1個序列重新構造成一個堆,這樣就會得到n個元素中的次大值。如此反覆執行,便能得到一個重小到大的有序序列。
void Bubble::goHeap()
{
// 初始化堆
// length / 2 - 1是二叉樹中最後一個非葉子結點的序號
for (int i = length / 2 -1; i >= 0; i--)
{
heapAdjust(i,length);
bubbleSignal(i);
QThread::msleep(static_cast<unsigned int>(mDelay));
}
// 交換堆頂元素和最後一個元素
for (int i = length-1; i >= 0; i--)
{
int temp;
temp = data[i];
data[i] = data[0];
data[0] = temp;
heapAdjust(0,i);
bubbleSignal(i);
QThread::msleep(static_cast<unsigned int>(mDelay));
}
for(int i = 0; i < length;i++){
bubbleSignal(i);
QThread::msleep(static_cast<unsigned int>(mDelay));
}
}
//構建一個大頂堆
void Bubble::heapAdjust(int i, int len)
{
int temp = data[i];
for(int j = 2*i+1;j <len; j=j*2+1){
if(j < len-1 && data[j] < data[j + 1]){
++j;
}
if(temp >= data[j])
break;
data[i] = data[j];
i = j;
bubbleSignal(i);
QThread::msleep(static_cast<unsigned int>(mDelay));
}
data[i] = temp;
}
運行結果
3.希爾排序
引用Wiki的介紹:
Shellsort,也稱爲Shell sort或Shell的方法,是一種就地比較排序。它可以看作是通過交換排序(冒泡排序)或通過插入排序(插入排序)的概括。該方法首先對彼此遠離的元素對進行排序,然後逐步減小要比較的元素之間的差距。從相距很遠的元素開始,它可以比一個簡單的最近鄰交換更快地將一些不合適的元素移動到位。唐納德·殼牌於1959年發佈了這種類型的第一個版本。Shellsort的運行時間在很大程度上取決於它使用的間隙序列。對於許多實際的變體,確定它們的時間複雜度仍然是一個未解決的問題。
基本思想:
先取一個小於n的整數d1作爲第一個增量,把文件的全部記錄分組。所有距離爲d1的倍數的記錄放在同一個組中。先在各組內進行直接插入排序;然後,取第二個增量d2<d1重複上述的分組和排序,直至所取的增量 =1( < …<d2<d1),即所有記錄放在同一組中進行直接插入排序爲止。實質上是一種進行多次分組插入排序的過程。
void Bubble::goShell()
{
int increasement = length;
int i, j, k;
do
{
// 確定分組的增量
increasement = increasement / 3 + 1;
for (i = 0; i < increasement; i++)
{
for (j = i + increasement; j < length; j += increasement)
{//這裏跟插入排序的思想一樣,只是增量不同
if (data[j] < data[j - increasement])
{
int temp = data[j];
for (k = j - increasement; k >= 0 && temp < data[k]; k -= increasement)
{
data[k + increasement] = data[k];
bubbleSignal(k);
QThread::msleep(static_cast<unsigned int>(mDelay));
}
data[k + increasement] = temp;
}
}
}
} while (increasement > 1);
for(int i = 0; i < length;i++){
bubbleSignal(i);
QThread::msleep(static_cast<unsigned int>(mDelay));
}
}
運行結果
4.總結
本文沒有詳細介紹各個排序算法的具體實現細節和邏輯,是因爲覺得個人並不能以足夠的通俗易懂語言講解出來,以免產生誤解,在此給大家推薦一本個人覺得非常好的書--《大話數據結構》。書裏面講解的十分詳細和生動,大家不妨去看看。