選擇排序
基本思想:各類排序的共同點,個人認爲可以把原始的數據序列,劃分爲有序序列與無序序列。有序序列開始可能爲0,在每一次操作(循環或者遞歸)後,有序序列數目會加1,無序序列數目會減一,代碼走完後,原本的數據序列完全變成有序序列。
關於選擇排序,例如初始序列是5,3,1,2,4.
1.搜索整個列表,找到最小項的位置,如果該位置不是列表第一項。則交換兩項位置。
2.從第二項開始一次往後搜索與替換。
def selectionSort(lyst):
for i in range (len(lyst)):
minIndex =i
for j in range (i+1,len(lyst)):
if (lyst[j]<lyst[minIndex]):
minIndex=j
if minIndex != i:
lyst[i],lyst[minIndex]=lyst[minIndex],lyst[i]
print("selectionSort:",lyst)
冒泡排序
這個就不多說了吧,比較交換,小頭冒泡或者大頭冒泡
def bubbleSort(lyst):
for i in range (len(lyst)):
for j in range(i+1,len(lyst)):
if lyst[j]<lyst[i]:
lyst[i],lyst[j]=lyst[j],lyst[i]
print("bubbleSort:",lyst)
優化:如果原本要排序的列表即爲有序列表,則添加一個bool變量用做判斷,如無交換則直接return
#冒泡排序的優化在於加上flag bool變量後,如果爲有序序列,則在
def bubbleSort_improved(lyst):
swapped=False
for i in range (len(lyst)):
for j in range (i+1,len(lyst)):
if lyst[j]<lyst[i]:
lyst[i],lyst[j]=lyst[j],lyst[i]
swapped = True
#兩層循環,在內層循環比較完後,交換變量swapped仍未發生改變,則直接輸出後return
if not swapped:
print("bubbleSort_improved:", lyst)
return
print("bubbleSort_improved:",lyst)
插入排序
def insertionSort_improved(lyst):
for i in range (1,len(lyst)):
itemToInsert=lyst[i]
# 利用j的自減來做insertIndex的定位,與break進行配合使用
j=i-1
while j >=0 :
if itemToInsert < lyst[j]:
lyst[j+1]=lyst[j]
else:
break
lyst[j+1]=itemToInsert
print("insertionSort_improved:",lyst)
快速排序
lyst=[8,7,3,1,2,3,6,0,12,7]
a=deepcopy(lyst)
#快速排序的基本思想爲:
"""兩個哨兵變量,一個pivot,j--,i++,ij相碰時將lyst[i]與pivot進行對調"""
"""需要把list作爲一個接口參數,不然deecopy的引用參數無法傳入,直接傳入lyst的引用,會修改原始的lyst變量"""
def quickSort(lyst,left,right):
#需要加上left和right的判斷,不然會超過最大迭代次數,導致棧內存溢出
if left>right:return
temp=lyst[left]
i,j=left,right
while(i<j):
while (lyst[j]>=temp and i<j):j -=1
while (lyst[i]<=temp and i<j):i +=1
if (i<j):
lyst[j],lyst[i]=lyst[i],lyst[j]
lyst[i],lyst[left]=lyst[left],lyst[i]
quickSort(lyst,left,i-1)
quickSort(lyst,i+1,right)
def print_quicksort(lyst):
quickSort(lyst,0,len(lyst)-1)
print("quickSort:",lyst)
print_quicksort(a)
print("initial list:",lyst)
歸併排序
"""快排與合併排序的基礎思想都是遞歸。對於合併排序每一次都拆成了兩個子序列,直到最後兩個子序列的長度均爲1,"""
def mergeSort(lyst):
if len(lyst)==1:
return lyst
#取拆分的中間位置,拆分成左右兩個子串
mid = len(lyst)//2
left=lyst[:mid]
right=lyst[mid:]
ll = mergeSort(left)
rl = mergeSort(right)
return merge(ll,rl)
#每次取小數放入新開闢的列表空間
#左右子序列進行比較,比較完成後會留下對應的需要加合的left和right序列
def merge(left,right):
res=[]
while len(left)>0 and len(right)>0:
if left[0] <= right[0]:
res.append(left.pop(0))
else:
res.append(right.pop(0))
res += left
res += right
return res
print("mergeSort:",mergeSort(lyst))
堆排序
https://blog.csdn.net/weixin_42348333/article/details/80991081
'''堆排序'''
'''1.從下至上,從右至左,對每個節點進行調整,以得到一個大頂堆'''
'''2.首尾互換,尾部元素已是有序序列,堆元素個數減1,此部分仍爲無序序列,繼續調整'''
def big_endian(lyst,start,end):
root = start
while True:
child = root * 2 + 1
if child > end:
break
if child+1 <= end and lyst[child] < lyst[child+1]:
child += 1
if lyst[root] < lyst[child]:
lyst[root], lyst[child] = lyst[child], lyst[root]
root = child
else:
break
def heap_sort(lyst):
first=len(lyst) // 2 - 1
for start in range (first, -1, -1):
big_endian(lyst, start, len(lyst)-1)
for end in range (len(lyst)-1, 0, -1):
lyst[0], lyst[end] = lyst[end], lyst[0]
big_endian(lyst, 0, end-1)
l = [3, 1, 4, 9, 6, 7, 5, 8, 2, 10]
print (l)
heap_sort(l)
print (l)