所有常见排序算法的python实现
排序算法是算法学习的基础,但形式多种多样,很多排序算法时间长不用,难免遗忘,笔者在此对常见的排序算法总结如下,算法原理可以自行Google,仅提供不同算法的python实现,帮助大家理解算法的执行过程,可以单步调试进行理解。仅供参考。
目录:
- 快速排序(递归)
- 快速排序(非递归)
- 归并排序(递归)
- 归并排序(非递归)
- 冒泡排序
- 选择排序
- 插入排序
- 堆排序:
- 递归版heapify
- 非递归版heapify
- 希尔排序
- 计数排序
代码
# @Author: feiyun
# @Date: 2020-05-01
# 快排递归
def quick_sort_r(nums):
if len(nums) < 2:
return nums
else:
p = nums[0]
left = [i for i in nums[1:] if i <= p]
right = [i for i in nums[1:] if i > p]
return quick_sort_r(left) + [p] + quick_sort_r(right)
# 快排非递归
def quick_sort(nums):
if len(nums) < 2:
return
stack = []
stack.append(len(nums) - 1)
stack.append(0)
while stack:
left = stack.pop()
right = stack.pop()
l = left
r = right
p = nums[l]
while l < r:
while l < r and nums[r] >= p:
r -= 1
while l < r and nums[l] <= p:
l += 1
if l != r:
nums[l], nums[r] = nums[r], nums[l]
nums[left] = nums[l]
nums[l] = p
if left < l - 1:
stack.append(l - 1)
stack.append(left)
if right > r + 1:
stack.append(right)
stack.append(r + 1)
return nums
# 归并排序
def merge_sort(nums):
def merge(ans, left, right):
while left and right:
if left[0] < right[0]:
ans.append(left.pop(0))
else:
ans.append(right.pop(0))
if left:
ans += left
if right:
ans += right
return ans
ans = []
n = len(nums)
mid = n // 2
if n < 2:
return nums
left = merge_sort(nums[:mid])
right = merge_sort(nums[mid:])
ans = merge(ans, left, right)
return ans
# 非递归归并
def merge_sort_no_r(nums):
def merge(nums, left, right, l):
ans = []
while left and right:
if left[0] < right[0]:
ans.append(left.pop(0))
else:
ans.append(right.pop(0))
if left:
ans += left
if right:
ans += right
for num in ans:
nums[l] = num
l += 1
n = len(nums)
ans = []
i = 1
while i < n:
l = 0
mid = l + i - 1
r = mid + i
while r < n:
merge(nums, nums[l:mid + 1], nums[mid + 1:r + 1], l)
l = r + 1
mid = l + i - 1
r = mid + i
if l < n and mid < n:
merge(nums, nums[l:mid + 1], nums[mid + 1:], l)
i += i
return nums
# 冒泡排序
def bubble_sort(nums):
n = len(nums)
for i in range(n - 1):
for j in range(n - i - 1):
if nums[j] > nums[j + 1]:
nums[j], nums[j + 1] = nums[j + 1], nums[j]
return nums
# 选择排序
def select_sort(nums):
n = len(nums)
for i in range(n):
min_idx = i
for j in range(i + 1, n):
if nums[j] < nums[min_idx]:
min_idx = j
nums[i], nums[min_idx] = nums[min_idx], nums[i]
return nums
# 插入排序
def insertion_sort(nums):
for i, num in enumerate(nums):
idx = i
while idx > 0 and nums[idx - 1] > num:
nums[idx] = nums[idx - 1]
idx -= 1
nums[idx] = num
return nums
# 堆排序
def heap_sort(nums):
n = len(nums)
first_parent = (n - 2) // 2
# 递归堆调整
def heapify(nums, i, n):
c1 = i * 2 + 1
c2 = i * 2 + 2
if c2 >= n or c1 >= n:
return
max = i
if c1 < n and nums[c1] > nums[max]:
max = c1
if c2 < n and nums[c2] > nums[max]:
max = c2
if max != i:
nums[i], nums[max] = nums[max], nums[i]
heapify(nums, max, n)
# 非递归堆调整
def heapify_no_r(nums, i, n):
# c1 = i * 2 + 1
# c2 = i * 2 + 2
# while c1 < n and c2 < n:
while i < n:
c1 = i * 2 + 1
c2 = i * 2 + 2
max = i
if c1 < n and nums[c1] > nums[max]:
max = c1
if c2 < n and nums[c2] > nums[max]:
max = c2
if max != i:
nums[i], nums[max] = nums[max], nums[i]
i = max
else:
break
while first_parent >= 0:
# heapify(nums, first_parent, n)
heapify_no_r(nums, first_parent, n)
first_parent -= 1
i = n - 1
while i >= 0:
nums[i], nums[0] = nums[0], nums[i]
# heapify(nums, 0, i)
heapify_no_r(nums, 0, i)
i -= 1
return nums
# 希尔排序
def shell_sort(nums):
if not nums:
return nums
n = len(nums)
if n < 2:
return nums
def insert_helper(nums, h, i):
tmp = nums[i]
idx = i
while idx - h >= 0 and nums[idx - h] > tmp:
nums[idx] = nums[idx - h]
idx -= h
nums[idx] = tmp
h = n // 2
while h > 0:
for i in range(h, n):
insert_helper(nums, h, i)
h //= 2
return nums
# 计数排序
def count_sort(nums):
c = [0 for _ in range(len(nums))]
for num in nums:
c[num - 1] += 1
ans = []
for i, n in enumerate(c):
ans.append([i] * n)
return ans
if __name__ == '__main__':
# nums = [3,6,7,2,4,9,1,5,8]
nums = [2,1,5,4,3]
# nums = [0,0,1,2,0,3]
# nums = quick_sort(nums)
# nums = merge_sort(nums)
# nums = bubble_sort(nums)
# nums = select_sort(nums)
# nums = insertion_sort(nums)
# nums = heap_sort(nums)
# nums = shell_sort(nums)
# nums = merge_sort_no_r(nums)
# nums = count_sort(nums)
nums = merge_sort(nums)
print(nums)