算法(Algorithm)是指解題方案的準確而完整的描述,是一系列解決問題的清晰指令,算法表明着用系統的方法描述解決問題的策略機制html
一個算法的優劣能夠用空間複雜度與時間複雜度來衡量。python
一個算法應該具備如下七個重要的特徵:算法
①有窮性(Finiteness):算法的有窮性是指算法必須能在執行有限個步驟以後終止; ②確切性(Definiteness):算法的每一步驟必須有確切的定義; ③輸入項(Input):一個算法有0個或多個輸入,以刻畫運算對象的初始狀況,所謂0個輸入是指算法自己定出了初始條件; ④輸出項(Output):一個算法有一個或多個輸出,以反映對輸入數據加工後的結果。沒有輸出的算法是毫無心義的; ⑤可行性(Effectiveness):算法中執行的任何計算步驟都是能夠被分解爲基本的可執行的操做步,即每一個計算步均可以在有限時間內完成(也稱之爲有效性); ⑥高效性(High efficiency):執行速度快,佔用資源少; ⑦健壯性(Robustness):對數據響應正確。
計算機科學中,算法的時間複雜度是一個函數,它定量描述了該算法的運行時間,時間複雜度經常使用大O符號(大O符號(Big O notation)數組
是用於描述函數漸進行爲的數學符號;大O,簡而言之能夠認爲它的含義是「order of」(大約是)數據結構
詳細請見:http://www.cnblogs.com/alex3714/articles/5910253.html函數
http://www.cnblogs.com/alex3714/articles/5474411.htmlui
名稱spa |
複雜度htm |
說明對象 |
備註 |
冒泡排序 |
O(N*N) |
將待排序的元素看做是豎着排列的「氣泡」,較小的元素比較輕,從而要往上浮 |
|
插入排序 Insertion sort |
O(N*N) |
逐一取出元素,在已經排序的元素序列中從後向前掃描,放到適當的位置 |
起初,已經排序的元素序列爲空 |
選擇排序 |
O(N*N) |
首先在未排序序列中找到最小元素,存放到排序序列的起始位置,而後,再從剩餘未排序元素中繼續尋找最小元素,而後放到排序序列末尾。以此遞歸。 |
|
快速排序 Quick Sort |
O(n *log2(n)) |
先選擇中間值,而後把比它小的放在左邊,大的放在右邊(具體的實現是從兩邊找,找到一對後交換)。而後對兩邊分別使用這個過程(遞歸)。 |
|
堆排序HeapSort |
O(n *log2(n)) |
利用堆(heaps)這種數據結構來構造的一種排序算法。堆是一個近似徹底二叉樹結構,並同時知足堆屬性:即子節點的鍵值或索引老是小於(或者大於)它的父節點。 |
近似徹底二叉樹 |
希爾排序 SHELL |
O(n1+£) 0<£<1 |
選擇一個步長(Step) ,而後按間隔爲步長的單元進行排序.遞歸,步長逐漸變小,直至爲1. |
|
箱排序 |
O(n) |
設置若干個箱子,把關鍵字等於 k 的記錄全都裝入到第k 個箱子裏 ( 分配 ) ,而後按序號依次將各非空的箱子首尾鏈接起來 ( 收集 ) 。 |
分配排序的一種:經過" 分配 " 和 " 收集 " 過程來實現排序。
|
它重複地走訪過要排序的數列,一次比較兩個元素,若是他們的順序錯誤就把他們交換過來。
走訪數列的工做是重複地進行直到沒有再須要交換,也就是說該數列已經排序完成。
思路:
相鄰兩個值進行比較,將較大的值放在右側,依次比較!
data_set = [9, 1, 22, 31, 45, 3, 6, 2, 11] # 第一種 # for j in range(len(data_set)): # for i in range(len(data_set) - j - 1): # if data_set[i] > data_set[i+1]: # # tmp = data_set[i] # data_set[i] = data_set[i+1] # data_set[i+1] = tmp # # data_set[i], data_set[i+1] = data_set[i+1], data_set[i] # 能夠把上面三行代碼簡化成一句 # print(data_set) # print(data_set) # 第二種 count = len(data_set) for i in range(0, count): for j in range(i + 1, count): if data_set[i] > data_set[j]: data_set[i], data_set[j] = data_set[j], data_set[i] print(data_set)
時間複雜度說明看下他的代碼複雜度會隨着N的增大而成指數型增加,而且根據判斷他時間複雜度爲Ο(n2)
插入排序的基本操做就是將一個數據插入到已經排好序的有序數據中,從而獲得一個新的、個數加一的有序數據,算法適用於少許數據的排序,時間複雜度爲O(n^2)。
是穩定的排序方法。插入算法把要排序的數組分紅兩部分:第一部分包含了這個數組的全部元素,但將最後一個元素除外(讓數組多一個空間纔有插入的位置),
而第二部分就只包含這一個元素(即待插入元素)。在第一部分排序完成後,再將這個最後元素插入到已排好序的第一部分中
思路:
一個列表默認分爲左側爲排序好的,咱們拿第一個元素舉例,他左邊的全是排序好的,他右側是沒有排序好的,若是右側的元素小於左側排序好的列表的元素就把他插入到合適的位置
data_list = [34, 45, 7, 89, 43, 2, 6, 4, 12, -9, 34, 88, ] # 第一種: # for i in range(len(data_list)): # while i > 0 and data_list[i] < data_list[i - 1]: # tmp = data_list[i] # data_list[i] = data_list[i-1] # 若是while條件成立把當前的值替換成他的上個值 # data_list[i - 1] = tmp # i -= 1 # 當上面的條件不成立時 # print(data_list) # print(data_list) # 第二種: # for i in range(1, len(data_list)): # key = data_list[i] # for j in range(i-1, -1, -1): # if data_list[j] > key: # data_list[j + 1] = data_list[j] # data_list[j] = key # print(data_list) # 第三種 count = len(data_list) for i in range(1, count): key = data_list[i] j = i - 1 while j >= 0: if data_list[j] > key: data_list[j + 1] = data_list[j] data_list[j] = key j -= 1 print(data_list)
基本思想:第1趟,在待排序記錄r1 ~ r[n]中選出最小的記錄,將它與r1交換;第2趟,在待排序記錄r2 ~ r[n]中選出最小的記錄,將它與r2交換;
以此類推,第i趟在待排序記錄r[i] ~ r[n]中選出最小的記錄,將它與r[i]交換,使有序序列不斷增加直到所有排序完畢。
思路:
第一次,從列表最左邊開始元素爲array[0],往右循環,從右邊元素中找到小於array[0]的元素進行交換,直到右邊循環完以後。
第二次,左邊第一個元素如今是最小的了,就從array[1],和剩下的array[1:-1]內進行對比,依次進行對比!
對比:
選擇排序和冒泡排序的區別就是,冒泡排序是相鄰的兩兩作對比,可是選擇排序是左側的「對比元素」和右側的列表內值作對比!
data_list = [34, 45, 7, 89, 43, 2, 6, 4, 12, -9, 34, 88, ] # 第一種 # for k in range(len(data_list)): # set_len_index = k # for i in range(k, len(data_list)): # if data_list[i] < data_list[set_len_index]: # set_len_index = i # tmp = data_list[set_len_index] # data_list[set_len_index] = data_list[k] # data_list[k] = tmp # print(data_list)s # print(data_list) # 第二種 count = len(data_list) for i in range(0, count): min = i # 假設默認第一個值最小 for j in range(i + 1, count): if data_list[min] > data_list[j]: min = j # 若是找到更小的,記錄更小的元素的下標 data_list[min], data_list[i] = data_list[i], data_list[min] print(data_list)
設要排序的數組是A[0]……A[N-1],首先任意選取一個數據(一般選用數組的第一個數)做爲關鍵數據,而後將全部比它小的數都放到它前面,
全部比它大的數都放到它後面,這個過程稱爲一趟快速排序。值得注意的是,快速排序不是一種穩定的排序算法,也就是說,
多個相同的值的相對位置也許會在算法結束時產生變更.他的時間複雜度是:O(nlogn) ~Ο(n2)
排序示例:
假設用戶輸入了以下數組:
建立變量i=0(指向第一個數據)[i所在位置紅色小旗子], j=5(指向最後一個數據)[j所在位置藍色小旗子], k=6(賦值爲第一個數據的值)。
i=0 j=3 k=6
i=2 j=3 k=6
若是i和j沒有碰頭的話,就遞加i找大的,尚未,就再遞減j找小的,如此反覆,不斷循環。注意判斷和尋找是同時進行的。
而後,對k兩邊的數據,再分組分別進行上述的過程,直到不能再分組爲止。
注意:第一遍快速排序不會直接獲得最終結果,只會把比k大和比k小的數分到k的兩邊。爲了獲得最後結果,
須要再次對下標2兩邊的數組分別執行此步驟,而後再分解數組,直到數組不能再分解爲止(只有一個數據),才能獲得正確結果。
data_list = [35, 45, 7, 89, 43, 2, 6, 4, 12, -9, 34, 88, 6, ] def quick_sort(data_list, left, right): if left >= right: return data_list key = data_list[left] low = left high = right while left < right: while left < right and data_list[right] >= key: right -= 1 data_list[left] = data_list[right] while left < right and data_list[left] <= key: left += 1 data_list[right] = data_list[left] data_list[right] = key quick_sort(data_list, low, left - 1) quick_sort(data_list, left + 1, high) return data_list if __name__ == '__main__': quick_sort(data_list, 0, len(data_list)-1) print(data_list)
def quick_sort(array, left, right): ''' :param array: :param left: 列表的第一個索引 :param right: 列表最後一個元素的索引 :return: ''' if left >= right: return low = left high = right key = array[low] # 第一個值 while low < high: # 只要左右未碰見 while low < high and array[high] > key: # 找到列表右邊比key大的值爲止 high -= 1 array[low] = array[high] # 此時直接 把key(array[low]) 跟 比它大的array[high]進行交換 array[high] = key while low < high and array[low] <= key: # 找到key左邊比key大的值,這裏爲什麼是<=而不是<呢?你要思考。。。 low += 1 array[high] = array[low] # 找到了左邊比k大的值 ,把array[high](此時應該剛存成了key) 跟這個比key大的array[low]進行調換 array[low] = key quick_sort(array, left, low-1) # 最後用一樣的方式對分出來的左邊的小組進行同上的作法 quick_sort(array, low+1, right) # 用一樣的方式對分出來的右邊的小組進行同上的作法 if __name__ == '__main__': array = [96, 14, 10, 9, 6, 99, 16, 5, 1, 3, 2, 4, 1, -123, -876, 13, 26, 18, 2, 45, 34, 23, 1, 7, 3, 22, 19, 2] print("before sort:", array) quick_sort(array, 0, len(array)-1) print("-------final -------") print(array)
後續更新...