各種排序演算法總結(Python,C )

2021-08-02 14:45:39 字數 3181 閱讀 8703

快找工作了,該複習演算法。這裡總結一下排序演算法。供以後查詢

當初研一的時候,老師留的實驗作業就是寫快速排序。其中pivot設為隨機選擇,與非隨機選擇。然後比較效能。

實際上做完實驗,發現合理的pivot會導致很平衡的劃分。我們需要故意設定乙個有序的序列(對應快排最壞的情況),選擇400000個int。效能還是差很多。將近10倍吧。

快排的思想 result = 【low】+pivot+【high】

然後對兩個子區間【low】、【high】分別遞迴呼叫即可。

時間複雜度o(nlogn)。最好o(nlogn),最壞o(n2)。

空間複雜度:依情況而定,有的是原址排序,有的是非原址的,有的是遞迴呼叫,有的是迴圈實現。

【段子】當初黃老師問起時間複雜度:我們都說是o(nlogn)。他:「」錯」。還有o(n2)的情況。遭到批評:「大學演算法誰教的?!」當然:快排之所以叫快排,是因為:只要不是待排序的陣列有序,那麼一定能達到很好的效能,上課他又舉例,還真是。而且nlogn它前面的係數很低。平均效能好像是1.44。

像nlogn的排序有好幾個:堆排序,歸併排序等。但是一般都弄不過快排。尤其是待排陣列長度很大的時候。

def

partition

(seq):

pivot,seq= seq[0],seq[1:]

low=[x for x in seq if x<= pi] #小於pivot放左邊

hi=[x for x in seq if x> pi] #大於pivot放右邊

return low,pivot,hi

defquicksort

(seq):

if len(seq) <= 1: #遞迴 base case

return seq

low,pivot,hi=partition(seq) #進行一次劃分

return quicksort(low)+[pivot]+quicksort(hi) #遞迴劃分

談到堆排序,我第一反應就是,有了快排幹嘛用堆排序??!

實際 上解決大資料top-k的問題,他就派上了用場。

1-堆是乙個完全二叉樹,因此可以用連續記憶體表示。堆可分為:大根堆(堆頂元素最大),小根堆(堆頂元素最小)。

2-堆的表示:用陣列(c),或者vector(c++)

陣列的【】

3-這裡空出第乙個位置。就可以滿足對於節點i他的父親是i/2。他的兒子2i(左),2i+1(右)。

4-建堆(n個元素)的時間為o(n)

堆排序過程(大根堆為例)

1- 將待排序的序列構造成乙個大頂堆 #此時堆頂為最大

2- 將它移走(其實就是將它與堆陣列的末尾元素交換,此時末尾元素就是最大值)。

3- 此時,需要維護前n-1個元素堆的性質(堆調整)。第n個元素已經有序

4- 調整完,此時又是乙個n-1個元素的大根堆,再取堆頂與堆中最後乙個元素交換。

5- 此時,前需要維護陣列前n-2個元素的堆性質(調整堆)。第n-1與第n個元素已經有序。

如此反覆執行,便能得到乙個有序序列了。

結論:大根堆,排序結果是公升序,小根堆排序結果是降序

演示:

# 調整堆  

defadjust_heap

(lists, i, size):

lchild = 2 * i + 1

rchild = 2 * i + 2

max = i

if i < size / 2:

if lchild < size and lists[lchild] > lists[max]:

max = lchild

if rchild < size and lists[rchild] > lists[max]:

max = rchild

if max != i:

lists[max], lists[i] = lists[i], lists[max]

adjust_heap(lists, max, size)

# 建立堆

defbuild_heap

(lists, size):

for i in range(0, (size/2))[::-1]:

adjust_heap(lists, i, size)

# 堆排序

defheap_sort

(lists):

size = len(lists)

build_heap(lists, size)

for i in range(0, size)[::-1]:

lists[0], lists[i] = lists[i], lists[0]

adjust_heap(lists, 0, i)

def

merge

(left, right):

i, j = 0, 0

result =

while i < len(left) and j < len(right):

if left[i] <= right[j]:

i += 1

else:

j += 1

result += left[i:]

result += right[j:]

return result

defmerge_sort

(lists):

# 歸併排序

if len(lists) <= 1:

return lists

num = len(lists) / 2

left = merge_sort(lists[:num])

right = merge_sort(lists[num:])

return merge(left, right)

排序演算法 插入排序 Python C

插入排序是一種最簡單直觀的排序演算法,它的工作原理是通過構建有序序列,對於未排序資料,在已排序序列中從後向前掃瞄,找到相應位置並插入。插入排序的平均時間複雜度和最壞情況是 o n 最好情況為o n 空間複雜度為o 1 因為是原地排序 in place 將第一待排序序列第乙個元素看做乙個有序序列,把第...

各種排序演算法總結

注 以下所講排序,以公升序排序為例!選擇排序 作者思路 在一組數中,選擇第乙個數標記為最小值,在剩下的數中找比它小的數,若找到則交換兩數,標記新的 最小值 然後繼續往下找,這樣一趟下來就可以找到一組數中第二小的值,第二次以第二個數作為最小值,如此迴圈下去。這是最簡單 最基礎的一種排序演算法。例子 1...

各種排序演算法總結

1 插入排序 void insertsort int a,int n a j 1 key 插入排序是穩定的排序,平均和最壞時間複雜度是o n 2 最好的時間複雜度是o n 對應於全部排好序的情況。2 氣泡排序 void bubblesort int a,intn 氣泡排序是穩定的排序,平均和最壞時間...