排序演算法穩定性的簡單形式化定義為:如果ai = aj,排序前ai在aj之前,排序後ai還在aj之前,則稱這種排序演算法是穩定的。通俗地講就是保證排序前後兩個相等的數的相對順序不變。
對於不穩定的排序演算法,只要舉出乙個例項,即可說明它的不穩定性;而對於穩定的排序演算法,必須對演算法進行分析從而得到穩定的特性。需要注意的是,排序演算法是否為穩定的是由具體演算法決定的,不穩定的演算法在某種條件下可以變為穩定的演算法,而穩定的演算法在某種條件下也可以變為不穩定的演算法。
選擇排序也是一種簡單直觀的排序演算法。它的工作原理很容易理解:初始時在序列中找到最小(大)元素,放到序列的起始位置作為已排序序列;然後,再從剩餘未排序元素中繼續尋找最小(大)元素,放到已排序序列的末尾。以此類推,直到所有元素均排序完畢。
**實現
def氣泡排序它重複地走訪過要排序的元素,依次比較相鄰兩個元素,如果他們的順序錯誤就把他們調換過來,直到沒有元素再需要交換,排序完成。這個演算法的名字由來是因為越小(或越大)的元素會經由交換慢慢「浮」到數列的頂端。swap(lyst, i, j):
temp =lyst[i]
lyst[i] =lyst[j]
lyst[j] =temp
#選擇排序
defselectionsort(lyst):
i =0
while i < len(lyst) - 1:
minindex =i
j = i + 1
while j
if lyst[j]
minindex =j
j += 1
if minindex !=i:
swap(lyst, minindex, i)
i += 1
氣泡排序演算法的運作如下:
比較相鄰的元素,如果前乙個比後乙個大,就把它們兩個調換位置。
對每一對相鄰元素作同樣的工作,從開始第一對到結尾的最後一對。這步做完後,最後的元素會是最大的數。
針對所有的元素重複以上的步驟,除了最後乙個。
持續每次對越來越少的元素重複上面的步驟,直到沒有任何一對數字需要比較。
**實現
def具體演算法描述如下:swap(lyst, i, j):
temp =lyst[i]
lyst[i] =lyst[j]
lyst[j] =temp
#氣泡排序
defbubblesort(lyst):
n =len(lyst)
while n > 1:
i = 1
while i
if lyst[i] < lyst[i - 1]:
swap(lyst, i, i - 1)
i += 1n -= 1
從第乙個元素開始,該元素可以認為已經被排序
取出下乙個元素,在已經排序的元素序列中從後向前掃瞄
如果該元素(已排序)大於新元素,將該元素移到下一位置
重複步驟3,直到找到已排序的元素小於或者等於新元素的位置
將新元素插入到該位置後
重複步驟2~5
**實現
def快速排序是由東尼·霍爾所發展的一種排序演算法。在平均狀況下,排序n個元素要o(nlogn)次比較。在最壞狀況下則需要o(n^2)次比較,但這種狀況並不常見。事實上,快速排序通常明顯比其他o(nlogn)演算法更快,因為它的內部迴圈可以在大部分的架構上很有效率地被實現出來。insertsort(lyst):
i=1while i
itemtoinsert=lyst[i]
j=i-1
while j>=0:
if itemtoinsert
lyst[j+1]=lyst[j]
j-=1
else
:
break
lyst[j+1]=itemtoinsert
i+=1
快速排序使用分治策略(divide and conquer)來把乙個序列分為兩個子串行。步驟為:
從序列中挑出乙個元素,作為"基準"(pivot).
把所有比基準值小的元素放在基準前面,所有比基準值大的元素放在基準的後面(相同的數可以到任一邊),這個稱為分割槽(partition)操作。
對每個分割槽遞迴地進行步驟1~2,遞迴的結束條件是序列的大小是0或1,這時整體已經被排好序了。
**實現
def歸併排序是建立在歸併操作上的一種有效的排序演算法,效率為o(nlogn),2023年由馮·諾伊曼首次提出。quicksort(lyst):
quicksorthelper(lyst,0,len(lyst)-1)
defquicksorthelper(lyst,left,right):
if left
pivotlocation=partition(lyst,left,right)
quicksorthelper(lyst,left,pivotlocation-1)
quicksorthelper(lyst,pivotlocation+1,right)
defpartition(lyst,left,right):
middle=(left+right)//2pivot=lyst[middle]
lyst[middle]=lyst[right]
lyst[right]=pivot
boundary=left
for index in
range(left,right):
if lyst[index]
swap(lyst,index,boundary)
boundary+=1swap(lyst,right,boundary)
return boundary
歸併排序的實現分為遞迴實現與非遞迴(迭代)實現。遞迴實現的歸併排序是演算法設計中分治策略的典型應用,我們將乙個大問題分割成小問題分別解決,然後用所有小問題的答案來解決整個大問題。非遞迴(迭代)實現的歸併排序首先進行是兩兩歸併,然後四四歸併,然後是八八歸併,一直下去直到歸併了整個陣列。
歸併排序演算法主要依賴歸併(merge)操作。歸併操作指的是將兩個已經排序的序列合併成乙個序列的操作,歸併操作步驟如下:
申請空間,使其大小為兩個已經排序序列之和,該空間用來存放合併後的序列
設定兩個指標,最初位置分別為兩個已經排序序列的起始位置
比較兩個指標所指向的元素,選擇相對小的元素放入到合併空間,並移動指標到下一位置
重複步驟3直到某一指標到達序列尾
將另一串行剩下的所有元素直接複製到合併序列尾
**實現
defmergesort(seq):
mid = len(seq) // 2lft, rgt =seq[:mid], seq[mid:]
if len(lft) > 1: lft =mergesort(lft)
if len(rgt) > 1: rgt =mergesort(rgt)
res =
while lft and
rgt:
if lft[-1] >= rgt[-1]:
else
: res.reverse()
return (lft or rgt) + res
python實現常用排序演算法
半夜醒來,閒來無事,寫寫排序演算法,興之所致,未來得及debug,有問題自己解決。coding utf 8 created on tue may 19 00 52 47 2015 氣泡排序 插入排序 1 每一步就像在一首已經排序的撲克牌中再插入一張牌,這張牌標記為value 2 從最後一張開始比較,...
幾種常用的排序演算法(二) python實現
5.折半插入排序,時間複雜度o n logn 演算法穩定。思路 假設將新元素,插入已經排好序的陣列當中,尋找插入位置的時候,採用了二分查詢,折半插入排序也叫二分插入排序。為陣列排序時,也是將第乙個元素作為已經排好序的陣列,迴圈陣列 若元素 arr i 小於 arr i 1 則為要插入的元素。利用二分...
常用的排序演算法實現
排序工具類 package sort public class sortutil public static void printarray int array 一 氣泡排序 package sort.bubble import sort.sortutil 氣泡排序 時間複雜度 n n public...