常见十大排序算法--python3实现

问题来源排序数组

问题描述:给你一个整数数组 nums,将该数组升序排列。

例子
输入:nums = [5,2,3,1]
输出:[1,2,3,5]

思路:这里没有什么好说的,有十种常见的排序算法。参考自@Sweetiee
在这里插入图片描述

1. 冒泡排序( O ( n 2 ) O(n^2) O(n2),稳定)

顾名思义,冒泡排序需要遍历n次,每次遍历都取出剩余元素中的最大值,最大值如同泡沫一样缓缓上升。

# 输入
a = [5, 4, 2, 3, 1]
# 冒泡排序
def bubble_sort(a):
	# 确定第i个最小值
	for i in range(len(a)):
		# 逐次交换比较,挑选出a[i:]中的最小值
		for j in range(len(a)-1, i, -1):
			if a[j] < a[j-1]:
				a[j], a[j-1] = a[j-1], a[j]
	return a

从程序可以看出来,只用到常数额外空间,因此,额外空间复杂度为 O ( 1 ) O(1) O(1)

2. 选择排序( O ( n 2 ) O(n^2) O(n2),不稳定)

选择排序意味着,同样进行n次遍历,每次遍历选出其中最小值。

# 输入
a = [5, 4, 2, 3, 1]
# 选择排序
def selection_sort(a):
	# 第i个最小值
	for i in range(len(a)):
		# 在a[i:]中选出最小值
		min_ind = i
		for j in range(i, len(a)):
			if a[j] < a[min_ind]:
				min_ind = j
		a[i], a[min_ind] = a[min_ind], a[i]
	return a

3. 插入排序( O ( n 2 ) O(n^2) O(n2),稳定)

同样n次遍历,每次遍历中,从未排序部分拿出一个数,依次与排序部分从末尾进行比较,如果拿出来的数小于排序部分的末尾,则交换;否则,停止。

# 输入
a = [5, 4, 2, 3, 1]
# 插入排序
def insertion_sort(a):
	# a[:i+1]为有序部分
	for i in range(len(a)-1):
		# 取出a[i+1],通过从大到小逐次比较插入有序部分
		for j in range(i, -1, -1):
			if a[j+1] < a[j]:
				a[j+1], a[j] = a[j], a[j+1]
			else:
				break
	return a		

4. 堆排序( O ( n l o g n ) O(nlogn) O(nlogn),稳定)

通过创建最大堆并维护最大堆,每次弹出堆顶,直至堆空。

# 输入
a = [5, 4, 2, 3, 1]
# 最大堆
class maxHeap:
	# 初始化堆
	def __init__(self):
		self.heap = []
		
	# 元素a[i]上浮
	def bubble(self, i):
		if i == 0:
			return 
		parent = (i-1) // 2
		if self.heap[i] > self.heap[parent]:
			self.heap[i], self.heap[parent] = self.heap[parent], self.heap[i]
			self.bubble(parent)
			
	# 元素a[i]下沉
	def sink(self, i, n):
		left = 2 * i + 1
		right = 2 * i + 2
		largest = i
		if left < n and self.heap[largest] < self.heap[left]:
			largest = left
		if right < n and self.heap[largest] < self.heap[right]:
			largest = right
		if largest != i:
			self.heap[i], self.heap[largest] = self.heap[largest], self.heap[i]
			self.sink(largest, n)
			
	# 根据数组a创建最大堆
	def buildHeap(self, a):
		self.heap = a
		for i in range(len(a)):
			self.bubble(i)
	
	# 将最大堆堆顶与最后一个元素交换,重新维护最大堆性质	
	def heapSort(self):	
		for i in range(len(self.heap)-1, -1, -1):
			self.heap[i], self.heap[0] = self.heap[0], self.heap[i]
			self.sink(0, i)
		return self.heap

# 堆排序的运用
obj = maxHeap()
obj.buildHeap(a)
print(obj.heapSort())

5. 归并排序

先递归,再处理。定义merge函数。

# 输入
a = [5, 4, 2, 3, 1]
# 归并排序
## merge函数
def merge(a, b):
	temp = []
	i, j = 0, 0
	while i < len(a) and j < len(b):
		if a[i] < b[j]:
			temp.append(a[i])
			i += 1
		else:
			temp.append(b[j])
			j += 1
	if i < len(a):
		temp.extend(a[i:])
	if j < len(b):
		temp.extend(b[j:])
	return temp
## 主函数
def mergeSort(a):
	if len(a) <= 1:
		return a
	mid = len(a) // 2
	left = mergeSort(a[:mid])
	right = mergeSort(a[mid:])
	return mergeSort(left, right)

6. 快速排序

先处理,再递归。

# 输入
a = [5, 4, 2, 3, 1]
# 快速排序
def quickSort(a):
	if len(a) <= 1:
		return a
	pivot = a[0]
	left = [ele for ele in a if ele < pivot]
	middle = [ele for ele in a if ele == pivot]
	right = [ele for ele in a if ele > pivot]
	return quickSort(left) + middle + quickSort(right)

7. 希尔排序

又名递减增量排序算法。

# 输入
a = [5, 4, 2, 3, 1]
# 希尔排序
def shellSort(a):
	if len(a) <= 1:
		return a
	gap = len(a) // 2
	while gap > 0:
		# 给定gap,做插入排序
		for i in range(gap, len(a)):
			j = i
			while j >= gap and a[j-gap] > a[j]:
				a[j-gap], a[j] = a[j], a[j-gap]
				j -= gap
		gap //= 2
	return a

8. 桶排序

非常快的算法,但是需要元素范围较小~

class Solution:
    def sortArray(self, nums: List[int]) -> List[int]:
        num_range = 50000
        backet = [0] * (2 * num_range + 1)
        for num in nums:
            backet[num + num_range] += 1
        j = 0
        for i in range(len(backet)):
            if backet[i]:
                while backet[i]:
                    nums[j] = i - num_range
                    j += 1
                    backet[i] -= 1
        return nums

9. 计数排序

计数排序也是一种桶排序。

10. 基数排序

基数排序相当于多轮桶排序,具体来说,就是从低到高逐位进行桶排序(需要确保元素值为非负数)。
参考@wangzaistoneRightNow

# 输入
a = [5, 4, 2, 3, 1]
# 基数排序
def radixSort(a, d): # d为最高位数,比如,550是三位数
	for k in range(d): # d轮桶排序
		s = [[] for i in range(10)]
		for num in a:
			m = int(num / (10 ** k) % 10) # 提取出数值的第i位数
			s[m].append(num)
		a = [j for i in a for j in i] # 第i位排序结果
	return a
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值