常用排序算法总结
实现稍微难点的三个算法:快排、归并、堆排序
快速排序
以下是一种写法(算法导论上是另一种写法,待补充)
def quickSort(data, start, end):
i = start
j = end
# i与j重合,一次排序结束
if i >= j:
return
# 设置最左边的数为基准值
flag = data[start]
while i < j:
while i < j and data[j] >= flag:
j -= 1
# 找到右边第一个小于基准的数赋值给左边i(此时左边i被记录在flag中)
data[i] = data[j]
while i < j and data[i] <= flag:
i += 1
# 找到左边第一个大于基准的数赋值给右边的j
data[j] = data[i]
# 循环完后把flag值放到i所在位置
data[i] = flag
# print(data)
# 除去i之外两段递归
quickSort(data, start, i - 1)
quickSort(data, i + 1, end)
if __name__ == "__main__":
data = [6, 5, 8, 2, 3, 1]
print(data)
quickSort(data, 0, len(data) - 1)
print(data)
冒泡排序
def bubbleSort(alist):
n = len(alist)
exchange = False
for i in range(n-1, 0, -1):
for j in range(0, i):
if alist[j] > alist[j+1]:
alist[j], alist[j+1] = alist[j+1], alist[j]
exchange = True
# 如果发现整个排序过程中没有交换,提前结束
if not exchange:
break
return alist
选择排序
- 选择排序是在冒泡排序的基础上优化的,提高了冒泡排序的性能
def selectionSort(alist):
n = len(alist)
for i in range(n - 1):
# 寻找[i,n]区间里的最小值
min_index = i
for j in range(i+1, n):
if alist[j] < alist[min_index]:
min_index = j
alist[i], alist[min_index] = alist[min_index], alist[i]
return alist
插入排序
def insertionSort(blist):
n = len(blist)
for i in range(1, n):
# 寻找a[i]合适的插入位置
temp = blist[i]
for j in range(i, 0, -1):
if temp < blist[j-1]:
blist[j] = blist[j-1]
else:
break
blist[j-1] = temp
print(blist)
return blist
希尔排序
- 希尔排序是在插入排序的基础上优化的,提高了插入排序的性能
def shell1Sort(data):
step = len(data) // 2
while step >= 1:
print("当前增量是:", step)
for i in range(step, len(data)):
for j in range(i-step, -step, -step):
if data[j] > data[j+step]:
data[j], data[j+step] = data[j+step], data[j]
step = int(step/2)
归并排序
def merge_sort(nums):
if len(nums) <= 1:
return nums
middle = len(nums) // 2
left_num = nums[:middle]
right_num = nums[middle:]
return merge(merge_sort(left_num), merge_sort(right_num))
def merge(left_num, right_num):
len_left = len(left_num)
len_right = len(right_num)
i = j = 0
result = []
# 比较left_num和left_right中的元素,按序添加到result中
while i < len_left and j < len_right:
if left_num[i] > right_num[j]:
result.append(right_num[j])
j += 1
else:
result.append(left_num[i])
i += 1
# 将j中的剩余元素添加到result中
if i == len_left and j < len_right:
for m in right_num[j:]:
result.append(m)
# 将i中的剩余元素添加到result中
if j == len_right and i < len_left:
for m in left_num[i:]:
result.append(m)
return result
堆排序(个人感觉算法很赞)
from collections import deque
# python中交换两个元素的位置
def swap(nums, i, j):
nums[i], nums[j] = nums[j], nums[i]
return nums
# 构造最大堆
def heap_adjust(nums, start, end):
temp = nums[start]
i = start
j = start * 2
while j <= end:
if j < end and nums[j] < nums[j + 1]:
j += 1
if temp < nums[j]:
nums[i] = nums[j]
i = j
j = i * 2
else:
break
nums[i] = temp
# 堆排序
def heap_sort(nums):
len_heap = len(nums) - 1
len_mid_heap = len_heap // 2
# 将序列调整为一个最大堆
for i in range(len_mid_heap):
heap_adjust(nums, len_mid_heap-i, len_heap)
print(nums)
# 将堆顶元素和堆末尾元素交换,将剩下元素调整为一个最大对
for i in range(len_heap-1):
swap(nums, len_heap-i, 1)
heap_adjust(nums, 1, len_heap-i-1)
print(nums)
return list(nums)[1:]
def main():
L = deque([50, 16, 30, 10, 60, 90, 2, 80, 70])
L.appendleft(0)
print(heap_sort(L))