排序方法:冒泡,選擇,快排,插入,並歸,堆排 - 邱乘屹的個人技術博客

排序方法:冒泡,選擇,快排,插入,並歸,堆排

冒泡

冒泡排序(英語:Bubble Sort)
是一種簡單的排序算法。它重複地遍歷要排序的數列,一次比較兩個元素,如果他們的順序錯誤就把他們交換過來。遍歷數列的工作是重複地進行直到沒有再需要交換,也就是說該數列已經排序完成。這個算法的名字由來是因爲越小的元素會經由交換慢慢“浮”到數列的頂端。

代碼實現:

def bubble_sort(alist):
    for j in range(len(alist)-1,0,-1):
        for i in range(j):
            if alist[i] > alist[i+1]:
                alist[i], alist[i+1] = alist[i+1], alist[i]
 
li = [54,26,93,17,77,31,44,55,20]
bubble_sort(li)
print(li)

選擇

選擇排序(Selection sort)是一種簡單直觀的排序算法。
它的工作原理如下。
首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置(索引、下標)
然後,再從剩餘未排序元素中繼續尋找最小(大)元素,
然後放到已排序序列的末尾。
以此類推,直到所有元素均排序完畢。

實現代碼:

def select_sort(alist):
    n = len(alist)
    # 需要進行n-1次選擇操作
    for i in range(n-1):
        # 記錄最小位置
        min_index = i
        # 從i+1位置到末尾選擇出最小數據
        for j in range(i+1, n):
            if alist[j] < alist[min_index]:
                min_index = j
        # 如果選擇出的數據不在正確位置,進行交換
        if min_index != i:
            alist[i], alist[min_index] = alist[min_index], alist[i]
 
alist = [54,226,93,17,77,31,44,55,20]
select_sort(alist)
print(alist)

快排

快速排序,又稱劃分交換排序,從無序隊列中挑取一個元素,把無序隊列分割成獨立的兩部分,其中一部分的所有數據都比另外一部分的所有數據都要小,然後再按此方法對這兩部分數據分別進行快速排序,整個排序過程可以遞歸進行,以此達到整個數據變成有序序列。
簡單來說:挑元素、劃分組、分組重複前兩步

實現代碼:

def quick(list):
    if len(list) < 2:
        return list

    tmp = list[0]  # 臨時變量 可以取隨機值
    left = [x for x in list[1:] if x <= tmp]  # 左列表
    right = [x for x in list[1:] if x > tmp]  # 右列表
    return quick(left) + [tmp] + quick(right)

li = [4,3,7,5,8,2]
print (quick(li))  # [2, 3, 4, 5, 7, 8]

並歸

歸併排序是採用分治法的一個非常典型的應用,另一個可以採用分治法的是快速排序,歸併算法比快速排序速度稍低。歸併排序的思想就是先遞歸分解數組,再合併數組。

將數組分解最小之後,然後合併兩個有序數組,基本思路是比較兩個數組的最前面的數,誰小就先取誰,取了後相應的指針就往後移一位。然後再比較,直至一個數組爲空,最後把另一個數組的剩餘部分複製過來即可。

代碼實現

def merge_sort(alist):
    if len(alist) <= 1:
        return alist
    num = len(alist)//2
    left = merge_sort(alist[:num])
    right = merge_sort(alist[num:])
    return merge(left, right)  # 合併
 
def merge(left, right):
    l, r = 0, 0
    result = []
    while l < len(left) and r < len(right):
        if left[l] < right[r]:  # 篩選排序將left與right最小元素按序加入新序列
            result.append(left[l])
            l += 1
        else:
            result.append(right[r])
            r += 1
    result += left[l:]
    result += right[r:]
    return result

堆排

堆排序也是一種選擇排序。個人覺得是簡單選擇排序的優化,藉助於二叉樹這種數據結構,每趟從待排序的記錄中選出關鍵字最小的記錄,順序放在已排序的記錄序列末尾,直到全部排序結束爲止。跟簡單選擇排序不同的是堆排序的待排序列是利用二叉樹這種數據結構存儲的。相比之下是更優化的。

代碼實現:

def HeapSort(input_list):
	
	#調整parent結點爲大根堆
	def HeapAdjust(input_list,parent,length):
		
		temp = input_list[parent]
		child = 2*parent+1
		
		while child < length:
			if child+1 <length and input_list[child] < input_list[child+1]:
				child +=1
			
			if temp > input_list[child]:
				break
			input_list[parent] = input_list[child]
			parent = child
			child = 2*child+1
		input_list[parent] = temp
	
	if input_list == []:
		return []
	sorted_list = input_list
	length = len(sorted_list)
	#最後一個結點的下標爲length//2-1
	#建立初始大根堆
	for i in range(0,length // 2 )[::-1]:
		HeapAdjust(sorted_list,i,length)
	
	for j in range(1,length)[::-1]:
		#把堆頂元素即第一大的元素與最後一個元素互換位置
		temp = sorted_list[j]
		sorted_list[j] = sorted_list[0]
		sorted_list[0] = temp
		#換完位置之後將剩餘的元素重新調整成大根堆
		HeapAdjust(sorted_list,0,j)
		print('%dth' % (length - j))
		print(sorted_list)
	return sorted_list
	
		
if __name__ == '__main__':
	input_list = [50,123,543,187,49,30,0,2,11,100]
	print("input_list:")
	print(input_list)
	sorted_list = HeapSort(input_list)
	print("sorted_list:")
	print(input_list)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章