算法搬运

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. 线性规划

原文地址:https://www.cnblogs.com/maigao/p/12853589.html