演算法複習筆記 排序演算法比較

2021-06-18 08:56:42 字數 3914 閱讀 6194

最近正好複習複習演算法,於是從排序演算法開始做乙個總結。以下的**均為原創,如果有任何問題,歡迎指正。簡單來講,排序演算法的實質是將長度為n的陣列中的數字按照從小到大或者從大到小的順利排列。

簡而言之,在不考慮演算法的情況下,我們可以把排序抽象為如下的乙個函式:array表示t型別的乙個陣列,num表示陣列的長度。本文假設我們實現的排序演算法都是按照從小到大的順序排列;從大到小的排列類似。

template

void order(t array, int num)

1)選擇演算法:基本思想是每次從陣列中選擇最小的數,將這個數與已排序的陣列最後一位交換。尋找第乙個數時,我們需要遍歷num個數才能判斷出最小的數;尋找第i個數時,由於我們已經成功的將前i-1個數按序排列,我們只需要遍歷num-i+1個數便能找到最小的數。

總而言之,時間複雜度為o(n2),而空間複雜度為o(1)。

template void selectsort(t array, int num)

}//從未排序數種找出最小值

if(cur != i)

//如果最小值不是未排序數種的第乙個,則交換最小值與未排序數的第乙個。

}}

總而言之,時間複雜度為o(n2),而空間複雜度為o(1)。

template void ******insertsort(t array, int num)

else

}//手中的牌是有序的,於是每抽一張就一次往前比較。新牌比前面的牌小便往前移動直到手牌整理完成

}}

3)折半插入演算法:基本思想和簡單插入演算法相同,但是新牌與手牌比較的時候不必一一比較(因為手牌已經有序排列了),我們可以用二分查詢的方法來將新牌左移

總而言之,時間複雜度有所提高,為o(nlogn),而空間複雜度為o(1)。

template void binaryinsertsort(t array, int num)

else

};//利用二分法找到插入的位置

if(low != i)

array[low] = temp;

}//如果插入的位置與新牌的位置不同,則將新牌插入

}}

4)希爾排序:基本思想和簡單插入演算法類似。簡單插入演算法每一次從距離為一的位置處抽取新值。如果資料分布比較分散,簡單插入演算法效率較低。於是,我們可以採用距離(稱之為步長)大於一的方式來抽取新值。例如,當步長為n時,陣列中相當於有n個平行的子陣列在做簡單插入演算法。運算之後,陣列變得更加為有序,於是我們可以不斷地縮小步長直到步長為1(簡單插入演算法),最終完成排序。當陣列越有序時,簡單插入演算法的效率越高。

總而言之,時間複雜度不容易計算,但實驗統計結果大約為n1.25到1.6n1.25,而空間複雜度為o(1)。希爾是一種不穩定的演算法。

template void shellsort(t array, int num)}}

//步長為step的簡單插入演算法

}step = (step - 1) / 3;//縮短步長

}}

5)歸併排序:初始時,我們假設我們得到了num個長度為1的子陣列;每一次運算時將兩個有序的子陣列合併成乙個父陣列。

總而言之,時間複雜度為o(n2),而空間複雜度為o(n)。

template t minvalue(t a, t b)

//將數值臨時儲存在臨時儲存陣列中

merge(temparray, array, cur, m - 1, len);

//合併相鄰子陣列

cur += len * 2;

//指標指向下一組子陣列

};//依次選擇相鄰的子陣列合併

len *= 2;

cur = 0;

//長度翻倍且重置指標

};delete temparray;

}

6)氣泡排序:通過依次交換兩個相鄰的兩個數,遍歷num個數後便將最大的數推送到了最後。推送第乙個數時,我們需要遍歷num個數才能推出最大值;推送第i個數時,由於我們已經成功的將i-1個數按序推出,我們只需要遍歷num-i+1個數便能推出當前最大的數。

總而言之,時間複雜度為o(n2),而空間複雜度為o(1)。

template void bubblesort(t array, int num)

}//依次交換相鄰的數將最大值推送到陣列尾部已排序的陣列最前端

}}

7)快速排序:對氣泡排序法的優化,基本思想也是將兩個數交換,但是我們希望盡量將較小的數交換到陣列左邊,將交大的數交換到陣列右邊。計算時我們從陣列中隨機選擇乙個數作為參考數,定義乙個指標從左向右遍歷,另乙個指標從右向左遍歷。第乙個指標尋找大於參考數的數,第二個指標尋找小於參考數的數,並將兩個數交換。當兩個指標相遇時一次迴圈結束,迴圈結束時相遇位置的左側的數均小於參考數,右側的數均大於參考數。我們可以遞迴地對左側和右側的陣列運用快速排序演算法。

總而言之,時間複雜度為o(nlogn),而空間複雜度為o(1)。

template void quick(t array, int low, int high)

//長度小於10時採用簡單插入演算法

t key = array[low];//利用第乙個數作為參考數

int i = low;

int j = high;

while(true)

//兩個指標相遇時這次迴圈結束

t temp = array[i];

array[i] = array[j];

array[j] = temp;

//交換兩個指標的數

};if(i == j)

else

}//針對左側右側迴圈採用快速迴圈

}//快速排序

template void quicksort(t array, int num)

8)堆排序:堆就是一顆樹,分為最小化堆與最大化堆,最小化堆的特點是父節點大於等於子節點。堆的儲存可以利用數字完成,位置為0的節點表示更節點。對於父節點n,左右子節點為n*2+1與n*2+2。

對於乙個父節點兩個子節點的子堆,我們可以分成方便的轉化使父節點大於等於子節點。整個堆的整理便是迴圈遞迴計算。

總而言之,建堆時間複雜度為o(n),刪除、插入等操作時間複雜度為)(logn)。而空間複雜度為o(n)。

template class heap

;template heap::heap(t array, int num)

//初始化已有資料

for(int i = num; i < num * 2; i++)

//初始化預留資料

buildheap();

//建堆

}template heap::~heap()

template void heap::buildheap()

//從樹倒數第二層,葉節點的父節點向根節點迴圈,置換每個三節點子堆

}template void heap::switchheap(int n)

//如果較小值比父節點小,交換

switchheap(n * 2 + 1);

switchheap(n * 2 + 2);

//置換子節點中的子堆

}else if(n * 2 + 1 < len)//只包含左節點

//如果子節點比父節點小,交換

switchheap(n * 2 + 1);

//置換子節點中的子堆

}//沒有子節點不計算

}template t heap::pop()

template void heap::insert(t value)

else

}//沿著樹枝將最小值向根節點推送

}

排序演算法複習筆記

排序演算法一般都會有幾個較為基礎通用的方法,如下表 方法名作用 issorted 判斷陣列是否有序 less int item1,int item2 比較第乙個引數是否小於等於第二個引數 exch int a,int b 交換這兩個索引位置的元素 show 列印陣列 sort 具體待實現的排序演算法...

演算法導論 比較排序演算法筆記

好幾天沒看 演算法導論 今天看了一天的排序演算法,印象第一的是基數演算法,因為居然違反我的乙個常識,它採用的是最低有效位進行排序的。插入排序 歸併排序 堆排序 快速排序,這些都是比較排序演算法 它們都是通過對元素進行比較操作來確定輸入陣列的有序次序,這些演算法可以用決策樹模型分析,可以證明任意比較排...

排序演算法複習

參考自 直接插入排序 從小到大排列 n個資料,第乙個資料平凡有序 假設前i 1個資料串有序,根據第i個的大小將第i個插入到此串中,則前i個的資料串也有序。因此可得到n個資料有序。插入方法 待插入元素為第i元素,數值存為temp,將 i 之前的元素 j 從第 i 1 元素開始與之比較 如果比temp大...