1. 程式人生 > >資料結構與演算法的那些事

資料結構與演算法的那些事

先佔坑,再補充。

常用演算法:

(1)排序:快排、歸併排序、插入排序、希爾排序、桶排序;

(2)分治演算法(divide-and-conquer),回溯演算法,貪婪演算法,動態規劃(DP);

(3)二分查詢(binary search);

 

一、排序演算法

演算法目標:

待排序陣列S ---> 排序後 ---> 從小到大遞增陣列S'

1、快排(quick sort)

演算法思路:

就是找出一個元素(樞紐元),然後將S劃分成兩個不相交的集合,其中一個集合S_small的所有元素都比樞紐元小,另外一個集合S_big的所有元素都比樞紐元大,然後對這兩個集合遞迴進行以上操作;快速排序也是一種遞迴的分治演算法。

演算法複雜度:O(NlogN)

演算法步驟:

(1)使用三數中值分割法來選出標兵P(也即在待排序陣列S的首尾和中間位置三個元素選出最大的作為標兵P);

(2)將標兵與陣列S最後一個元素交換位置;

(3)指標i指向陣列S的首元素,指標j指向陣列S的倒數第二個元素,指標i從左往右跳過比標兵P小的元素,停在大於等於P的元素位置上,而指標j從右往左跳過比標兵P大的元素,停在小於等於P的元素位置上,然後指標i和指標j交換指向元素的值;

(4)重複步驟(3),直到指標i在指標j的右邊,也即i > j;

(5)把指標i指向的元素和S的最後一個元素交換位置,此時指標i左邊的元素集合為S_small,都比指標i指向的元素小,但是無序,而指標i右邊的元素集合為S_big,都比指標i指向的元素大,但是無序;

(6)對S_small和S_big遞迴執行(1)-(5)。

程式碼實現:

 

2、歸併排序(merge sort)

演算法思路:

把問題轉化為將兩個有序的序列合併成一個有序的序列,也即將一個無序陣列等分為兩個無序陣列,然後對這兩個無序陣列應用歸併排序演算法變為有序陣列,再合併,得到結果,這其實就是典型的分治策略。

演算法複雜度:O(NlogN)

演算法步驟:

如果S的元素個數小於2,則直接返回S,否則對S的前半部分和後半部分遞迴呼叫該歸併演算法,然後將返回結果,即兩個有序的數組合並,即為最後的排序結果。

程式碼實現:

 

三、二分查詢(binary search)

演算法目標:

對於已經排序的陣列S,查詢元素target是否在S中,如果在,則返回位置,否則返回-1;

演算法思路:

(1)將target與S[middle]元素比較,如果target > S[middle],則說明target元素有可能在S的middle+1~right區間中,否則就說明target元素有可能在S的left~middle-1區間中;

(2)對(1)中得到的新區間位置,重複(1),直到left > right;

程式碼實現: