超炫的6種排序演算法的Python實現
阿新 • • 發佈:2018-11-27
1.氣泡排序
思路:遍歷列表,每一輪每次比較相鄰兩項,將無序的兩項交換,下一輪遍歷比前一輪比較次數減1。
-
def bubble_sort(a_list):
-
for passnum
in range(len(a_list)
-1,
0,
-1
):
-
for i
in range(passnum):
-
if a_list[i] > a_list[i+
1]:
-
a_list[i], a_list[i+
1
] = a_list[i+
1], a_list[i]
改進:遍歷期間沒有交換,則認為已排序,可以停止。
-
def short_bubble_sort(a_list):
-
exchanges =
True
-
passnum = len(a_list) -
1
-
while passnum >
0
and exchanges:
-
exchanges =
False
-
for i
in range(passnum):
-
if a_list[i] > a_list[i+
1]:
-
exchanges =
True
-
a_list[i], a_list[i+
1] = a_list[i+
1], a_list[i]
-
passnum = passnum -
1
動畫演示:
2.選擇排序
思路:遍歷列表,每次遍歷選出最大的放在合適的位置。
-
def selection_sort(a_list):
-
for fillslot
in range(len(a_list)
-1,
0,
-1):
-
position_max=
0
-
for location
in range(
1, fillslot+
1):
-
if a_list[location] > a_list[position_max]:
-
position_max = location
-
a_list[fillslot], a_list[position_max] = a_list[position_max], a_list[fillslot]
動畫演示:
3.插入排序
思路:每一步都將待插入的資料按大小插入到已排序的資料中的合適位置。
-
def insertion_sort(a_list):
-
for index
in range(
1, len(a_list)):
-
cur_value = a_list[index]
-
pos = index
-
while pos >
0
and a_list[pos
-1] > cur_value:
-
a_list[pos] = a_list[pos
-1]
-
pos = pos -
1
-
a_list[pos] = cur_value
動畫演示:
4.希爾排序
思路:分解為多個子列表進行插入排序,不是連續分,而是通過增量。
-
def shell_sort(a_list):
-
sublist_count = len(a_list)
-
while sublist_count >
0:
-
for start_position
in range(sublist_count):
-
gap_insertion_sort(a_list, start_position, sublist_count)
-
sublistcount = sublistcount //
2
-
-
def gap_insertion_sort(a_list, start, gap):
-
for i
in range(start+gap, len(a_list), gap):
-
current_value = a_list[i]
-
position = i
-
while position >= gap
and a_list[position-gap] > current_value:
-
a_list[position] = a_list[position-gap]
-
position = position - gap
-
a_list[position] = current_value
5.歸併排序
思路:分而治之,不斷拆分為一半,直至項數為0或1,然後排序合併。需要額外空間。
-
def merge_sort(a_list):
-
if len(a_list) >
1:
-
mid = len(a_list) //
2
-
lefthalf = a_list[:mid]
-
righthalf = a_list[mid:]
-
merge_sort(lefthalf)
-
merge_sort(righthalf)
-
i=
0
-
j=
0
-
k=
0
-
while i < len(lefthalf)
and j < len(righthalf):
-
if lefthalf[i] < righthalf[j]:
-
a_list[k] = lefthalf[i]
-
i = i +
1
-
else:
-
a_list[k] = righthalf[j]
-
j = j +
1
-
k=k+
1
-
while i < len(lefthalf):
-
a_list[k] = lefthalf[i]
-
i = i +
1
-
k = k +
1
-
while j < len(righthalf):
-
a_list[k] = righthalf[j]
-
j = j +
1
-
k = k +
1
動畫演示:
6.快速排序
思路:與歸併一樣使用分而治之,不使用額外記憶體,特點是樞軸值。
-
def quick_sort(a_list):
-
quick_sort_helper(a_list,
0, len(a_list)
-1)
-
-
def quick_sort_helper(a_list, first, last):
-
if first < last:
-
splitpoint = partition(a_list, first, last)
-
quick_sort_helper(a_list, first, splitpoint
-1)
-
quick_sort_helper(a_list, splitpoint+
1, last)
-
-
def partition(a_list, first, last):
-
pivotvalue = a_list[first]
-
leftmark = first +
1
-
rightmark = last
-
done =
False
-
while
not done:
-
while leftmark <= rightmark
and a_list[leftmark] <= pivotvalue:
-
leftmark = leftmark +
1
-
while a_list[rightmark] >= pivotvalue
and rightmark >= leftmark:
-
rightmark = rightmark
-1
-
if rightmark < leftmark:
-
done =
True
-
else:
-
a_list[leftmark], a_list[rightmark] = a_list[rightmark], a_list[leftmark]
-
a_list[first], a_list[rightmark] = a_list[rightmark], a_list[first]
動畫演示:
說明:
1.參考https://interactivepython.org/runestone/static/pythonds/SortSearch/toctree.html
2.動畫來自https://visualgo.net/en 截圖
1.氣泡排序
思路:遍歷列表,每一輪每次比較相鄰兩項,將無序的兩項交換,下一輪遍歷比前一輪比較次數減1。
-
def bubble_sort(a_list):
-
for passnum
in range(len(a_list)
-1,
0,
-1):
-
for i
in range(passnum):
-
if a_list[i] > a_list[i+
1]:
-
a_list[i], a_list[i+
1] = a_list[i+
1], a_list[i]
改進:遍歷期間沒有交換,則認為已排序,可以停止。
-
def short_bubble_sort(a_list):
-
exchanges =
True
-
passnum = len(a_list) -
1
-
while passnum >
0
and exchanges:
-
exchanges =
False
-
for i
in range(passnum):
-
if a_list[i] > a_list[i+
1]:
-
exchanges =
True
-
a_list[i], a_list[i+
1] = a_list[i+
1], a_list[i]
-
passnum = passnum -
1
動畫演示:
2.選擇排序
思路:遍歷列表,每次遍歷選出最大的放在合適的位置。
-
def selection_sort(a_list):
-
for fillslot
in range(len(a_list)
-1,
0,
-1):
-
position_max=
0
-
for location
in range(
1, fillslot+
1):
-
if a_list[location] > a_list[position_max]:
-
position_max = location
-
a_list[fillslot], a_list[position_max] = a_list[position_max], a_list[fillslot]
動畫演示:
3.插入排序
思路:每一步都將待插入的資料按大小插入到已排序的資料中的合適位置。
-
def insertion_sort(a_list):
-
for index
in range(
1, len(a_list)):
-
cur_value = a_list[index]
-
pos = index
-
while pos >
0
and a_list[pos
-1] > cur_value:
-
a_list[pos] = a_list[pos
-1]
-
pos = pos -
1
-
a_list[pos] = cur_value
動畫演示:
4.希爾排序
思路:分解為多個子列表進行插入排序,不是連續分,而是通過增量。
-
def shell_sort(a_list):
-
sublist_count = len(a_list)
-
while sublist_count >
0:
-
for start_position
in range(sublist_count):
-
gap_insertion_sort(a_list, start_position, sublist_count)
-
sublistcount = sublistcount //
2
-
-
def gap_insertion_sort(a_list, start, gap):
-
for i
in range(start+gap, len(a_list), gap):
-
current_value = a_list[i]
-
position = i
-
while position >= gap
and a_list[position-gap] > current_value:
-
a_list[position] = a_list[position-gap]
-
position = position - gap
-
a_list[position] = current_value
5.歸併排序
思路:分而治之,不斷拆分為一半,直至項數為0或1,然後排序合併。需要額外空間。
-
def merge_sort(a_list):
-
if len(a_list) >
1:
-
mid = len(a_list) //
2
-
lefthalf = a_list[:mid]
-
righthalf = a_list[mid:]
-
merge_sort(lefthalf)
-
merge_sort(righthalf)
-
i=
0
-
j=
0
-
k=
0
-
while i < len(lefthalf)
and j < len(righthalf):
-
if lefthalf[i] < righthalf[j]:
-
a_list[k] = lefthalf[i]
-
i = i +
1
-
else:
-
a_list[k] = righthalf[j]
-
j = j +
1
-
k=k+
1
-
while i < len(lefthalf):
-
a_list[k] = lefthalf[i]
-
i = i +
1
-
k = k +
1
-
while j < len(righthalf):
-
a_list[k] = righthalf[j]
-
j = j +
1
-
k = k +
1
動畫演示:
6.快速排序
思路:與歸併一樣使用分而治之,不使用額外記憶體,特點是樞軸值。
-
def quick_sort(a_list):
-
quick_sort_helper(a_list,
0, len(a_list)
-1)
-
-
def quick_sort_helper(a_list, first, last):
-
if first < last:
-
splitpoint = partition(a_list, first, last)
-
quick_sort_helper(a_list, first, splitpoint
-1)
-
quick_sort_helper(a_list, splitpoint+
1, last)
-
-
def partition(a_list, first, last):
-
pivotvalue = a_list[first]
-
leftmark = first +
1
-
rightmark = last
-
done =
False
-
while
not done:
-
while leftmark <= rightmark
and a_list[leftmark] <= pivotvalue:
-
leftmark = leftmark +
1
-
while a_list[rightmark] >= pivotvalue
and rightmark >= leftmark:
-
rightmark = rightmark
-1
-
if rightmark < leftmark:
-
done =
True
-
else:
-
a_list[leftmark], a_list[rightmark] = a_list[rightmark], a_list[leftmark]
-
a_list[first], a_list[rightmark] = a_list[rightmark], a_list[first]