經典排序演算法的總結及Python實現

2022-08-31 07:03:11 字數 3960 閱讀 3567

排序的穩定性和複雜度

不穩定:

選擇排序(selection sort)— o(n2)

快速排序(quicksort)— o(nlogn) 平均時間, o(n2) 最壞情況; 對於大的、亂序串列一般認為是最快的已知排序

希爾排序 (shell sort)— o(nlogn)

穩定:

插入排序(insertion sort)— o(n2)

氣泡排序(bubble sort) — o(n2)

歸併排序 (merge sort)— o(n log n); 需要 o(n) 額外儲存空間

每種排序的原理和python實現

選擇排序

遍歷陣列,遍歷到i時,a0,a1...ai-1是已經排好序的,然後從i到n選擇出最小的,記錄下位置,如果不是第i個,則和第i個元素交換。此時第i個元素可能會排到相等元素之後,造成排序的不穩定。

1

defselection_sort(a):

2for i in range(0, len(a) - 1):

3 index =i

4for j in range(i + 1, len(a)):

5if a[index] >a[j]:

6 index =j

7 a[i], a[index] = a[index], a[i]

快速排序

快速排序首先找到乙個基準,下面程式以第乙個元素作為基準(pivot),然後先從右向左搜尋,如果發現比pivot小,則和pivot交換,然後從左向右搜尋,如果發現比pivot大,則和pivot交換,一直到左邊大於右邊,此時pivot左邊的都比它小,而右邊的都比它大,此時pivot的位置就是排好序後應該在的位置,此時pivot將陣列劃分為左右兩部分,可以遞迴採用該方法進行。快排的交換使排序成為不穩定的。

1

defpatition(l,low,high):

2 left=low

3 right=high

4 pos=l[low]

5while left6while pos>=l[left]:

7 left+=1

8while pos9 right-=1

10if left11 l[right],l[left]=l[left],l[right]

12 l[low]=l[right]

13 l[right]=pos

14return

right

1516

defquick_sort(l,low,high):

17if low18 k=patition(l,low,high)

19 quick_sort(l,low,k-1)

20 quick_sort(l,k+1,high)

希爾排序

希爾排序是對插入排序的優化,基於以下兩個認識:1. 資料量較小時插入排序速度較快,因為n和n2差距很小;2. 資料基本有序時插入排序效率很高,因為比較和移動的資料量少。

因此,希爾排序的基本思想是將需要排序的序列劃分成為若干個較小的子串行,對子序列進行插入排序,通過則插入排序能夠使得原來序列成為基本有序。這樣通過對較小的序列進行插入排序,然後對基本有序的數列進行插入排序,能夠提高插入排序演算法的效率。

希爾排序的時間複雜度和增量的選擇策略有關,上述增量方法造成希爾排序的不穩定性。

1

defshellsort(nums):

2 step=int(len(nums)/2)

3while step>0:

4for i in

range(step,len(nums)):

5if step<=i and nums[i-step]>nums[i]:

6 nums[i-step],nums[i]=nums[i],nums[i-step]

7 i-=step

8 step=int(step/2)

9return nums

插入排序

遍歷陣列,遍歷到i時,a0,a1...ai-1是已經排好序的,取出ai,從ai-1開始向前和每個比較大小,如果小於,則將此位置元素向後移動,繼續先前比較,如果不小於,則放到正在比較的元素之後。可見相等元素比較是,原來靠後的還是拍在後邊,所以插入排序是穩定的。

當待排序的資料基本有序時,插入排序的效率比較高,只需要進行很少的資料移動。

1

definsert_sort(a):

2 length =len(a)

3for i in range(1, length):

4 x =a[i]5#

如果第i個元素小於第j個,則第j個向後移動,

6for j in range(i, -1, -1):

7if x < a[j - 1]:

8 a[j] = a[j - 1]

9else:10

#如果不小於,則放在正在比較的元素之後

11break

12 a[j] = x

氣泡排序

氣泡排序的名字很形象,實際實現是相鄰兩節點進行比較,大的向後移乙個,經過第一輪兩兩比較和移動,最大的元素移動到了最後,第二輪次大的位於倒數第二個,依次進行。

1

defbubble_sort(a):

2 n =len(a)

3for j in range(0, n - 1):

4for i in range(0, n - 1 -j):

5if a[i] > a[i + 1]:

6 a[i], a[i + 1] = a[i + 1], a[i]

歸併排序

歸併排序是採用分治法(divide and conquer)的乙個非常典型的應用。首先考慮下如何將將二個有序數列合併。這個非常簡單,只要從比較二個數列的第乙個數,誰小就先取誰,取了後就在對應數列中刪除這個數。然後再進行比較,如果有數列為空,那直接將另乙個數列的資料依次取出即可。這需要將待排序序列中的所有記錄掃瞄一遍,因此耗費o(n)時間,而由完全二叉樹的深度可知,整個歸併排序需要進行.logn.次,因此,總的時間複雜度為o(nlogn)。

歸併排序在歸併過程中需 要與原始記錄序列同樣數量的儲存空間存放歸併結果,因此空間複雜度為o(n)。

歸併演算法需要兩兩比較,不存在跳躍,因此歸併排序是一種穩定的排序演算法。

1

defmerge(a,b):

2 merged=

3 i, j =0, 0

4while iand j5if a[i]67 i+=1

8else:9

10 j+=1

11merged.extend(a[i:])

12merged.extend(b[j:])

13return

merged

1415

defmerge_sort(c):

16if len(c)<=1:

17return

c18 mid=len(c)//2

19 a=merge_sort(c[:mid])

20 b=merge_sort(c[mid:])

21return merge(a,b)

經典排序演算法總結

排序演算法是離散數學和資料結構學科最基本的演算法,雖然知道這些排序演算法的名字,但是一直沒有研究過它們的實現原理。現在把它們收集起來,並一一親自實現,來加深對排序演算法的理解。1,氣泡排序 最簡單的排序演算法,從第乙個元素開始比較相鄰元素大小,如果前邊元素大於後邊元素則交換位置,否則將下標移到下乙個...

經典排序演算法總結

插入排序 選擇排序 歸併排序 排序方法 平均情況 最好最差 空間複雜度 穩定性氣泡排序o n2 o n 2 o n o n o n2 o n 2 o 1 o 1 穩定快速排序o nlogn o nlog n o nlogn o nlog n o n2 o n 2 o nlogn o nlog n 不...

排序演算法 經典的排序演算法總結

一 氣泡排序 1.氣泡排序的思想 對於乙個長度為n的陣列,從小到大進行排序。0 n 1範圍內,兩兩進行比較與交換,結果是最大的元素放在陣列的最後面 即n 1位上 0 n 2範圍內,兩兩進行比較與交換,結果是第二大元素放在最後面 即n 2位上 重複上述過程,直到範圍縮小到只有0位的乙個元素為止。2.例...