交換排序
歸併排序
基數排序
外表排序
各種內排序演算法比較與應用
各排序演算法實現的時候只是簡單的實現了演算法的思想,沒考慮特殊輸入的處理(如空陣列,只包含1個元素的陣列,low>high,high超出陣列長度等情況)。面試手撕**時,記得考慮各種特殊情況。直接插入排序
基本思想
python實現
def insert_sort(arr):
for i in range(1, len(arr)):
key = arr[i]
# if arr[i] > arr[i-1]:
j = i - 1
while arr[j] > key and j >= 0:
arr[j+1] = arr[j]
j -= 1
arr[j+1] = key
return arr
if __name__ == '__main__':
arr = [9,7,8,6,2,4,3,5,1]
# arr =
# arr = [1]
# arr = [9,8,7,6,5,4,3,2,1]
# arr = [1,2,3,4,5,6,7,8,9]
# print(build_max_heap(arr, len(arr)-1))
print(insert_sort(arr))
折半插入排序
希爾排序
氣泡排序
關鍵步驟:比較、交換
python實現
def bubble_sort(arr):
for i in range(len(arr)):
flag = false
j = len(arr) - 1
while j > i:
if arr[j-1] > arr[j]:
arr[j-1], arr[j] = arr[j], arr[j-1]
flag = true
j -= 1
if not flag: return arr
return arr
def bubble_sort2(arr):
flag = false
for i in range(len(arr)):
for j in range(len(arr)-1-i):
if arr[j] > arr[j+1]:
arr[j], arr[j+1] = arr[j+1], arr[j]
flag = true
if not flag: return arr
return arr
if __name__ == '__main__':
arr = [7,9,8,6,2,4,3,5,1]
print(bubble_sort(arr))
空間效率:o(1)
時間效率:
比較次數:n(n-1)/2
移動次數:3n(n-1)/2
最好:o(n^2)
平均:o(n^2)
穩定性:穩定
快速排序
時間效率:
穩定性:不穩定。l(3,2,2)
快排是所有內排序演算法中平均效能最優的排序演算法
選擇排序得基本思想:每一趟(例如第i趟)在後面n-i+1(n=1,2…,n-1)個待排序元素中選取關鍵字最小得元素,作為有序子串行得第i個元素,直到n-1趟排序完,待排序元素只剩下乙個,就不用選了。
簡單選擇排序
穩定性:不穩定(l[2,2,1],交換元素的時候,可能導致第i個元素與其含有相同關鍵字元素得相對位置發生變化)
堆排序堆的定義:n個關鍵字序列l[1…n]稱為堆,當且僅當該序列滿足:
大根堆:l(i)>=l(2i)且l(i)>=l(2i+1)
小根堆:l(i)<=l(2i)且l(i)<=l(2i+1)
基本思想:堆排序是一種樹形選擇排序方法,它的特點是:在排序過程中,將l[1…n]看成是一棵完全二叉樹的順序儲存結構,利用完全二叉樹中雙親節點和孩子節點之間的內在關係,在當前無序區中選擇最大(小)關鍵元素。通常將l[0]設定為哨兵,節點從l[1]開始。python實現
def build_max_heap(arr, len):
for i in range(len//2, 0, -1):
adjust_down(arr, i, len)
return arr
def adjust_down(arr, k, length):
temp = arr[k]
i = k
j = 2 * i
while j <= length:
if j <= length and j + 1 <= length:
if arr[j] < arr[j+1]:
j += 1
if arr[j] > temp:
arr[i] = arr[j]
i = j
j = 2 * i
else:
break
arr[i] = temp
def heap_sort(arr, len):
build_max_heap(arr, len)
for i in range(len, 1, -1):
arr[i], arr[1] = arr[1],arr[i]
adjust_down(arr, 1, i-1)
return arr
if __name__ == '__main__':
arr = [0,7,8,6,2,4,3,5,1]
# arr =
# arr = [1]
# arr = [9,8,7,6,5,4,3,2,1]
# arr = [1,2,3,4,5,6,7,8,9]
# print(build_max_heap(arr, len(arr)-1))
len = len(arr) - 1
print(heap_sort(arr, len))
二路歸併排序
比較 時間複雜度
o(n):簡單選擇排序、直接插入排序、氣泡排序
o(n·ln):堆排序、快排(平均o(n·ln)、最壞o(n^2))、歸併(最好最壞平均都是)
空間複雜度
o(1):簡單選擇排序、插入排序、氣泡排序、希爾排序、堆排序
o(n·ln):快排(平均n·ln、最壞n)
o(n):歸併
穩定性
穩定:插入排序、氣泡排序、歸併排序、基數排序
不穩定:簡單選擇排序、快排、希爾、堆
基於比較的排序:直接插入、冒泡、簡單選擇、希爾、快排、堆排、歸併
分配式排序:基數排序、桶排序
應用 選取排序方法需要考慮的因素
待排序的元素數目n
元素本身資訊量的大小
關鍵字的結構及其分布情況
穩定性要求
語言工具的條件,儲存結構及輔助空間的大小
排序演算法總結
若n較小(n<=50),則可以採用直接插入排序或簡單選擇排序。由於直接插入排序所需的記錄移動操作較簡單選擇排序多,因此當記錄本身資訊量較大時,用簡單選擇排序較好
若檔案的初始狀態基本有序,則使用直接插入排序或氣泡排序為宜
若n較大時,則應選擇時間複雜度為o(n·ln)的排序演算法。快排、堆排序、歸併。快排被認為是目前基於比較的內排序中最好的方法,當關鍵字隨機分布時,快排平均時間最短。堆排序的輔助空間少於快排,並且不會出現快排可能出現的最壞情況。但兩者都是不穩定的,歸併排序是穩定的
若n很大,記錄的關鍵字位數較少且可以分解時,採用基數排序較好。
當記錄本身資訊量較大,為了避免耗費大量時間移動記錄,可用鍊錶作為儲存結構。
排序演算法總結
1 直接插入排序 1 穩定性 穩定 2 適用情況 待排記錄規模較小,或者記錄已經基本有序 2 希爾排序 1 穩定性 不穩定 2 特點 希爾排序的執行時間依賴於增量序列,它的效率比直接插入排序有較大的改進。3 氣泡排序 1 穩定性 穩定 2 特點 當待排記錄基本有序是,氣泡排序是不錯的選擇 但由於氣泡...
排序演算法總結
1 選擇排序 選擇排序的思想是依次從待排序數列中選擇最大 小 的 第二大 小 的等等,然後依次重新排列為有序數列。void selectionsort int a,int n if min i 時間複雜度o n 2 2 歸併排序 void merge int a,int left,int mid,i...
排序演算法總結
學習了這麼多的排序演算法,還沒有做個總結,呵呵 氣泡排序 氣泡排序是最慢的排序演算法。在實際運用中它是效率最低的演算法。它通過一趟又一趟地比較陣列中的每乙個元素,使較大的資料下沉,較小的資料上公升。它是 o n 2 的演算法。快速排序 快速排序是乙個就地排序,分而治之,大規模遞迴的演算法。從本質上來...