算法搬運


1. 選擇排序 0(n*n)

 1 //選擇算法
 2 void selectionSort(int arr[], int n){
 3     for(int i = 0 ; i < n ; i ++){
 4         // 尋找[i, n)區間里的最小值
 5         int minIndex = i;
 6         for( int j = i + 1 ; j < n ; j ++ )
 7             if( arr[j] < arr[minIndex] )
 8                 minIndex = j;
 9        //交換位置  
10         swap( arr[i] , arr[minIndex] );
11     }
12 }    

 

2. 插入排序

//插入排序
void insertionSort(T arr[], int n){

    for( int i = 1 ; i < n ; i ++ ) {

        // 尋找元素arr[i]合適的插入位置
       
        for( int j = i ; j > 0 ; j-- )
            if( arr[j] < arr[j-1] )
                swap( arr[j] , arr[j-1] );
            else
                break;

    return;
}

3. 冒泡排序

 1 // 冒泡排序
 2 template<typename T>
 3 void bubbleSort( T arr[] , int n){
 4 
 5     int newn; // 使用newn進行優化
 6 
 7     do{
 8         newn = 0;
 9         for( int i = 1 ; i < n ; i ++ )
10             if( arr[i-1] > arr[i] ){
11                 swap( arr[i-1] , arr[i] );
12 
13                 // 記錄最后一次的交換位置,在此之后的元素在下一輪掃描中均不考慮
14                 newn = i;
15             }
16         n = newn;
17     }while(newn > 0);
18 }

  

4. 歸並排序

 1 // 歸並排序算法, 對arr[l...r]的范圍進行排序
 2 template<typename T>
 3 void __mergeSort2(T arr[], int l, int r){
 4 
 5     //  對於小規模數組, 使用插入排序
 6     if( r - l <= 15 ){
 7         insertionSort(arr, l, r);
 8         return;
 9     }
10 
11     int mid = (l+r)/2;
12     __mergeSort2(arr, l, mid);
13     __mergeSort2(arr, mid+1, r);
14 
15     // 對於arr[mid] <= arr[mid+1]的情況,不進行merge
16     if( arr[mid] > arr[mid+1] )
17         __merge(arr, l, mid, r);
18 }

 

5. 希爾排序

// 希爾排序
template<typename T>
void shellSort(T arr[], int n){
    // 計算 increment sequence: 1, 4, 13, 40, 121...
    int h = 1;
    while( h < n/3 )
        h = 3 * h + 1;

    while( h >= 1 ){

        // h-sort the array
        for( int i = h ; i < n ; i ++ ){

            // 對 arr[i], arr[i-h], arr[i-2*h], arr[i-3*h]... 使用插入排序
            T e = arr[i];
            int j;
            for( j = i ; j >= h && e < arr[j-h] ; j -= h )
                arr[j] = arr[j-h];
            arr[j] = e;
        }
        // 因子
        h /= 3;
    }
}    

 

6. 自底向上的歸並排序

// 使用自底向上的歸並排序算法
template <typename T>
void mergeSortBU(T arr[], int n){

    // 對於小數組, 使用插入排序優化
    for( int i = 0 ; i < n ; i += 16 )
        insertionSort(arr,i,min(i+15,n-1));

    for( int sz = 16; sz < n ; sz += sz )
        for( int i = 0 ; i < n - sz ; i += sz+sz )
            // 對於arr[mid] <= arr[mid+1]的情況,不進行merge
            if( arr[i+sz-1] > arr[i+sz] )
                __merge(arr, i, i+sz-1, min(i+sz+sz-1,n-1) );

    // Merge Sort BU 也是一個O(nlogn)復雜度的算法,雖然只使用兩重for循環

}

 

7. 快速排序

 1 // 對arr[l...r]部分進行partition操作
 2 // 返回p, 使得arr[l...p-1] < arr[p] ; arr[p+1...r] > arr[p]
 3 template <typename T>
 4 int __partition(T arr[], int l, int r){
 5 
 6     T v = arr[l];
 7 
 8     int j = l; // arr[l+1...j] < v ; arr[j+1...i) > v
 9     for( int i = l + 1 ; i <= r ; i ++ )
10         if( arr[i] < v ){
11             j ++;
12             swap( arr[j] , arr[i] );
13         }
14 
15     swap( arr[l] , arr[j]);
16 
17     return j;
18 }
19 
20 // 對arr[l...r]部分進行快速排序
21 template <typename T>
22 void __quickSort(T arr[], int l, int r){
23 
24     if( l >= r )
25         return;
26 
27     int p = __partition(arr, l, r);
28     __quickSort(arr, l, p-1 );
29     __quickSort(arr, p+1, r);
30 }
31 
32 template <typename T>
33 void quickSort(T arr[], int n){
34 
35     __quickSort(arr, 0, n-1);
36 }

 

8. 雙路快速排序

9. 三路快速排序

 1 // 遞歸的三路快速排序算法
 2 template <typename T>
 3 void __quickSort3Ways(T arr[], int l, int r){
 4 
 5     // 對於小規模數組, 使用插入排序進行優化
 6     if( r - l <= 15 ){
 7         insertionSort(arr,l,r);
 8         return;
 9     }
10 
11     // 隨機在arr[l...r]的范圍中, 選擇一個數值作為標定點pivot
12     swap( arr[l], arr[rand()%(r-l+1)+l ] );
13 
14     T v = arr[l];
15 
16     int lt = l;     // arr[l+1...lt] < v
17     int gt = r + 1; // arr[gt...r] > v
18     int i = l+1;    // arr[lt+1...i) == v
19     while( i < gt ){
20         if( arr[i] < v ){
21             swap( arr[i], arr[lt+1]);
22             i ++;
23             lt ++;
24         }
25         else if( arr[i] > v ){
26             swap( arr[i], arr[gt-1]);
27             gt --;
28         }
29         else{ // arr[i] == v
30             i ++;
31         }
32     }
33 
34     swap( arr[l] , arr[lt] );
35 
36     __quickSort3Ways(arr, l, lt-1);
37     __quickSort3Ways(arr, gt, r);
38 }
39 
40 template <typename T>
41 void quickSort3Ways(T arr[], int n){
42 
43     srand(time(NULL));
44     __quickSort3Ways( arr, 0, n-1);
45 }

 

10. 二分查找法

 1 // 用遞歸的方式寫二分查找法
 2 template<typename T>
 3 int __binarySearch2(T arr[], int l, int r, T target){
 4 
 5     if( l > r )
 6         return -1;
 7 
 8     //int mid = (l+r)/2;
 9     // 防止極端情況下的整形溢出,使用下面的邏輯求出mid
10     int mid = l + (r-l)/2;
11 
12     if( arr[mid] == target )
13         return mid;
14     else if( arr[mid] > target )
15         return __binarySearch2(arr, l, mid-1, target);
16     else
17         return __binarySearch2(arr, mid+1, r, target);
18 }
19 
20 template<typename T>
21 int binarySearch2(T arr[], int n, T target){
22 
23     return __binarySearch2( arr , 0 , n-1, target);
24 }

 

9.  散列函數

 1 # 創建一個book的空散列表
 2 book = dict()
 3 
 4 # 向散列表添加數據--> "apple": key  0.45: value
 5 book["apple"] = 0.45
 6 book["pin"] = 0.80
 7 book["banana"] = 2.45
 8 book["orange"] = 1.23
 9 book["pee"] = 0.75
10 
11 # 查詢散列表
12 print(book["apple"].hex())
13 print(book["pin"].hex())
14 print(book["banana"].hex())

 

10. 廣度優先搜索

 1 # 尋找最短路徑
 2 
 3 # 聲明一個圖--> 用於存放數據
 4 graph = {}
 5 graph["you"] = ["alice", "bob", "claire"]
 6 graph["bob"] = ["anuj", "peggy"]
 7 graph["alice"] = ["peggy"]
 8 graph["claire"] = ["thom", "jonny"]
 9 graph["anuj"] = []
10 graph["peggy"] = []
11 graph["thom"] = []
12 graph["jonny"] = []
13 
14 # 聲明一個隊列,可使用函數deque來創建一個雙端隊列
15 from collections import deque
16 search_queue = deque()
17 search_queue += graph["you"]   # 將你的鄰居都加入到這個搜索隊列中
18 
19 # 是否存在
20 def person_is_seller(name):
21  return name[-1] == 'm'
22 
23 # 實現算法
24 def search(name):
25     search_queue = deque()
26     search_queue += graph[name]
27     searched = []              # 標記已經查詢過的人
28     while search_queue:        # search_queue: 隊列不為空時
29         person = search_queue.popleft()      # 取得隊列第一個
30         if not person in searched:           # 是否在查詢過的列表中
31             if person_is_seller(person):
32                 print (person + " is a mango seller!")
33                 return True
34             else:
35                 search_queue += graph[person]
36                 searched.append(person)
37     return False
38 
39 
40 
41 # 輸出結果
42 if __name__ == '__main__':
43     search("you")

 

11. 深度優先搜索

12. 狄克斯特拉算法

 1 # 尋找帶權圖的最短路徑
 2 
 3 # 聲明一個散列表
 4 graph = {}   # 相等於 :graph = dict()
 5 
 6 graph["start"] = {}
 7 graph["start"]["a"] = 6
 8 graph["start"]["b"] = 2
 9 
10 # 添加其他節點及其鄰居。
11 graph["a"] = {}
12 graph["a"]["fin"] = 1
13 graph["b"] = {}
14 graph["b"]["a"] = 3
15 graph["b"]["fin"] = 5
16 
17 # 創建終點節點--.>  沒有任何的鄰居
18 graph["fin"] = {}
19 
20 # 用一個散列表來存儲每個節點的開銷。
21 infinity = float("inf")
22 costs = {}
23 costs["a"] = 6
24 costs["b"] = 2
25 costs["fin"] = infinity
26 
27 # 存儲父節點的散列表
28 parents = {}
29 parents["a"] = "start"
30 parents["b"] = "start"
31 parents["fin"] = None
32 
33 # 數組,用於記錄處理過的節點
34 processed = []
35 
36 # 尋找最小開銷的節點
37 def find_lowest_cost_node(costs):
38     lowest_cost = float("inf")
39     lowest_cost_node = None
40     for node in costs:                     # 遍歷所有的節點
41         cost = costs[node]
42         if cost < lowest_cost and node not in processed:   # 如果當前節點的開銷更低且未處理過
43             lowest_cost = cost             # 就將其視為開銷最低的節點
44             lowest_cost_node = node
45     return lowest_cost_node
46 
47 # 算法實現
48 node = find_lowest_cost_node(costs)   # 在未處理的節點中找出開銷最小的節點
49 while node is not None:            # 這個while循環在所有節點都被處理過后結束
50     cost = costs[node]
51     neighbors = graph[node]
52     for n in neighbors.keys():     # 遍歷當前節點的所有鄰居
53         new_cost = cost + neighbors[n]
54         if costs[n] > new_cost:     # 如果經當前節點前往該鄰居更近
55             costs[n] = new_cost     # 就更新該鄰居的開銷
56             parents[n] = node       # 同時將該鄰居的父節點設置為當前節點
57     processed.append(node)          # 將當前節點標記為處理過
58     node = find_lowest_cost_node(costs)   # 找出接下來要處理的節點,並循環
59 
60 
61 # 輸出結果
62 print(cost)

 

13. 貪婪算法

 1 # 貪婪算法
 2 
 3 # 總區域
 4 states_needed = set(["mt", "wa", "or", "id", "nv", "ut", "ca", "az"])
 5 
 6 # 廣播
 7 stations = {}
 8 stations["kone"] = set(["id", "nv", "ut"])
 9 stations["ktwo"] = set(["wa", "id", "mt"])
10 stations["kthree"] = set(["or", "nv", "ca"])
11 stations["kfour"] = set(["nv", "ut"])
12 stations["kfive"] = set(["ca", "az"])
13 
14 # 輸出廣播集合
15 final_stations = set()
16 
17 while states_needed:
18   best_station = None
19   states_covered = set()
20   for station, states in stations.items():
21     covered = states_needed & states
22     if len(covered) > len(states_covered):
23       best_station = station
24       states_covered = covered
25 
26   states_needed -= states_covered
27   final_stations.add(best_station)
28 
29 print(final_stations)

 

14. 近似算法

15. 動態規划

16. K最近鄰算法

17. SHA算法

18. 線性規划


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM