經典排序方法(一) 冒泡 插入 歸併 快排

2021-09-24 02:49:20 字數 4257 閱讀 3858

插入排序的工作原理是通過構建有序序列,對於未排序的序列,在已排序的序列中從後向前掃瞄,找到相應的位置並插入。

從第乙個元素開始,該元素可以認為已經被排序

取出下乙個元素,在已經排序的元素序列中從後向前掃瞄

如果已排序的元素大於新元素,將已排序元素移動到下一位置

重複步驟三,直到找到已排序的元素小於或者等於新元素的位置

將新元素插入該位置後

重複步驟2~5

def

insert_sort

(list):

n =len(

list

)for i in

range(1

,n):

temp =

list

[i] j = i -

1while j >=

0and temp <

list

[j]:

list

[j+1]=

list

[j] j -=

1list

[j+1

]= temp

return

list

氣泡排序重複地走訪要排序的數列,一次比較兩個元素,如果他們的順序錯誤就把他們交換過來,

比較相鄰的元素,如果第乙個比第二個大,就交換它們

對每一對相鄰元素作同樣的工作。

def

bubble_sorted

(list_)

: new_list =

list

(list_)

list_len =

len(new_list)

for i in

range

(list_len -1)

:for j in

range

(list_len -

1, i,-1

):if new_list[j]

< new_list[j -1]

: new_list[j]

, new_list[j -1]

= new_list[j -1]

, new_list[j]

return new_list

歸併排序的基本思想在於把兩個已經排序的序列合併成乙個序列。其大概可以分為兩個步驟:

在歸併操作中,有兩種不同的方法,分別為遞迴法(top-down)和迭代法(bottom-up),在此我們主要討論迭代法。其基本過程如下:

申請空間,使其大小為兩個已排序子串行之和;

設定兩個指標,最初位置分別為兩個已經排序子串行的起始位置;

比較兩個指標所指向的元素,選擇較小的放入到合併空間,並將指標移動到下一位之;

重複步驟3,直到某一指標到達序列末尾

將另一列所剩下的元素直接複製到合併序列末尾

def

merge

(left, right)

: result =

while left and right:

if left[0]

<= right[0]

:0))

#pop取出元素,並刪除序列對應的元素

else:0

))if left:

result += left

if right:

result += right

# print("result",result) #推薦利用print函式檢視輸出,進一步理解遞迴

return result

defmerge_sort

(l):

iflen

(l)<=1:

# when only 1 element, just return it

return l

mid =

len(l)//2

left = l[

:mid]

right = l[mid:

] left = merge_sort(left)

right = merge_sort(right)

# conquer sub-problem recursively

return merge(left, right)

# return the answer of sub-problem

>>

> test =[8

,7,6

,5,4

,3,2

,1]>>

> merge_sort(test)

對於該演算法的理解,推薦各位讀者參考:

快速排序的基本思想在於,對於待排序序列中的某乙個基準數,找到乙個位置k,並將基準數移動至位置k.使得以k為分界點,左邊的數都小於這個基準數。下面以序列6 1 2 7 9 3 4 5 10 8為例,簡單說明快速排序的基本原理。

首先為了簡便起見,我們選擇6作為我們的基準數,並初始化兩個指標分別指向序列起始和末尾位置。為了便於描述,分別命名為指標i指標j。此時指標i指向6,指標j指向8。

指標j首先開始移動,直到遇到第乙個小於基準數的元素停下,此時其指向了元素5。然後指標i開始自左向右移動,並遇到了第乙個大於基準的元素停下,此時其指向了元素7

交換兩個指標對應的元素。此時的序列為6 1 2 5 9 3 4 7 10 8.

重複步驟2~3,直到兩個指標相遇,說明該輪探索結束,交換指標元素和基準數,此時序列為3 1 2 5 4 6 9 7 10 8。至此,基準元素6的左側均比6小,右側均比6大。

將舊基準元素的兩側視為新的子串行,重複上述過程。

該例子可以用下圖表達:

上述例子可以被抽象為:

挑選基準值(pivot);

分割:重新排序序列,所有比基準值小的元素擺放在基準前面,所有比基準值大的元素擺在基準後面。在這個分割結束後,對基準值的排序結束。

遞迴排序子串行。

需要注意的是,上述演算法實現過程主要用了分治法(divide and conquer)的思想,需要ω(n

)\omega(n)

ω(n)

的額外儲存空間。所以現在又有原地分割(in-place)的方法對此加以改進。在原地分割中,在移動元素的過程中,基準元素最後的擺放位置也被尋找。故而節省了一定的額外儲存空間,其具體**實現如下:

def

quick_sort

(lst)

: lst = lst[:]

n =len(lst)

defpartition

(lst,start,end)

:

i = start -

1 pivotindex = end

pivot = lst[end]

for j in

range

(start,end)

:if lst[j]

< pivot:

i = i +

1if i != j:

lst[i]

, lst[j]

= lst[j]

, lst[i]

lst[i+1]

,lst[pivotindex]

= lst[pivotindex]

,lst[i+1]

#print("in part",lst,i+1)

return i+

1def

sort

(lst,start,end)

:if start >= end:

return

p = partition(lst,start,end)

sort(lst,start,p-1)

sort(lst,p+

1,end)

#print("in sort",lst)

sort(lst,

0,n-1)

return lst

排序演算法 冒泡 插入 歸併 快排

整理了一下幾種常見的排序演算法,包括冒泡 插入 歸併 快排。還有另外幾種待整理 堆排序 希爾排序 桶排序 直接上 include include include using namespace std void swap int a,int b 最簡單的氣泡排序,時間複雜度o n n void bu...

排序 冒泡,快排,歸併。

1 冒泡 就是每次相鄰的比較,較大的移到後面,一次後就移動最大的到最後面了。include void maopao int a,int len void main int len sizeof a sizeof a 0 maopao a,len for int x1 0 x12 快速排序,用遞迴來理...

排序演算法 插入 選擇 冒泡 快排 歸併

可以找一些帖子理解下幾類排序演算法或者聽下陳越姥姥在mooc上的資料結構 選擇類排序 交換類排序 歸併排序 基數排序 拓撲排序 從待排序的n個記錄中的第二個記錄開始,依次與前面的記錄比較並尋找插入的位置,每次外迴圈結束後,將當前的數插入到合適的位置。void sort insert int a,in...