题目
给你一个整数数组 nums
,请你将该数组升序排列。
示例 1:
输入:nums = [5,2,3,1]
输出:[1,2,3,5]
示例 2:
输入:nums = [5,1,1,2,0,0]
输出:[0,0,1,1,2,5]
提示:
1 <= nums.length <= 50000
-50000 <= nums[i] <= 50000
排序算法总结
一、冒泡排序
代码1:
def bubble_sort(list):
length = len(list)
# 第一级遍历
for index in range(length):
# 第二级遍历
for j in range(1, length - index):
if list[j - 1] > list[j]:
# 交换两者数据,这里没用temp是因为python特性元组。
list[j - 1], list[j] = list[j], list[j - 1]
return list
这种排序其实还可以稍微优化一下,添加一个标记,在排序已完成时,停止排序。
代码2:
def bubble_sort_flag(list):
length = len(list)
for index in range(length):
# 标志位
flag = True
for j in range(1, length - index):
if list[j - 1] > list[j]:
list[j - 1], list[j] = list[j], list[j - 1]
flag = False
if flag:
# 没有发生交换,直接返回list
return list
return list
二、选择排序
def selection_sort(list):
n=len(list)
for i in range (0,n):
min = i
for j in range(i+1,n):
if list[j] < list[min]:
min = j
list[min], list[i] = list[i], list[min]
return list
三、插入排序
代码1:
def insert_sort(list):
n = len(list)
for i in range(1, n):
# 后一个元素和前一个元素比较
# 如果比前一个小
if list[i] < list[i - 1]:
# 将这个数取出
temp = list[i]
# 保存下标
index = i
# 从后往前依次比较每个元素
for j in range(i - 1, -1, -1):
# 和比取出元素大的元素交换
if list[j] > temp:
list[j + 1] = list[j]
index = j
else:
break
# 插入元素
list[index] = temp
return list
代码2:
def insert_sort(data):
for k in range(1, len(data)):
cur = data[k]
j = k
while j > 0 and data[j - 1] > cur:
data[j] = data[j - 1]
j -= 1
data[j] = cur
return data
四、希尔排序
def shell_sort(arr):
# 取整计算增量(间隔)值
gap = len(arr) // 2
while gap > 0:
# 从增量值开始遍历比较
for i in range(gap, len(arr)):
j = i
current = arr[i] # 保存当前待插入的数
# 元素与它同列的前面的每个元素比较,如果比前面的小则互换
while j - gap >= 0 and current < arr[j - gap]:
arr[j] = arr[j - gap]
j -= gap
arr[j] = current # 待插入的数的正确位置
# 缩小增量(间隔)值
gap //= 2
return arr
五、归并排序
# 递归法
def merge_sort(list):
# 认为长度不大于1的数列是有序的
if len(list) <= 1:
return list
# 二分列表
middle = len(list) // 2
left = merge_sort(list[:middle])
right = merge_sort(list[middle:])
# 最后一次合并
return merge(left, right)
# 合并
def merge(left, right):
l,r=0,0
result=[]
while l<len(left) and r<len(right):
if left[l] <right[r]:
result.append(left[l])
l+=1
else:
result.append(right[r])
r +=1
# 直到某一指针到达序列尾,将另一序列剩下的所有元素直接复制到合并序列尾
reslut += left[l:]
result += right[r:]
return result
六、快速排序
代码1:
def partition(arr,i,j):
p=arr[i] # 基准值为第一个值
while i!=j:
while i<j and p<=arr[j]:
j-=1
arr[i]=arr[j]
while i<j and p>arr[i]:
i+=1
arr[j]=arr[i]
arr[i]=p
return i
def quick_sort(arr,i,j):
if i<j:
mid=partition(arr,i,j)
quick_sort(arr,i,mid-1)
quick_sort(arr,mid+1,j)
代码2:
# 分区函数
def partition(arr,low,high):
# i用来表示遍历过程中,所有比基准小的数组成的子序列中的最后一个元素的索引
# 最后i+1即为基准在原序列中的位置
i = low-1
pivot = arr[high] # 基准值为最后一个值
for j in range(low , high):
# 当前元素小于或等于 pivot
if arr[j] <= pivot:
i += 1
arr[i],arr[j] = arr[j],arr[i]
arr[i+1],arr[high] = arr[high],arr[i+1]
return (i+1)
# 快速排序函数
def quickSort(arr,low,high):
if low < high:
pi = partition(arr,low,high)
quickSort(arr, low, pi-1)
quickSort(arr, pi+1, high)
代码3:
def quick_sort(list):
less = []
pivotList = []
more = []
# 递归出口
if len(list) <= 1:
return list
else:
# 将第一个值做为基准
pivot = list[0]
for i in list:
# 将比基准小的值放到less数列
if i < pivot:
less.append(i)
# 将比基准大的值放到more数列
elif i > pivot:
more.append(i)
# 将和基准相同的值保存在基准数列
else:
pivotList.append(i)
# 对less数列和more数列继续进行排序
less = quick_sort(less)
more = quick_sort(more)
return less + pivotList + more
代码4:
def qsort(arr):
if len(arr) <= 1:
return arr
else:
pivot = arr[0]
less = [x for x in arr[1:] if x < pivot]
greater = [x for x in arr[1:] if x >= pivot]
return qsort(less) + [pivot] + qsort(greater)
七、堆排序
def heap_sort(nums):
# 调整堆
# 迭代写法
def adjust_heap(nums, startpos, endpos):
newitem = nums[startpos]
pos = startpos
childpos = pos * 2 + 1
while childpos < endpos:
rightpos = childpos + 1
if rightpos < endpos and nums[rightpos] >= nums[childpos]:
childpos = rightpos
if newitem < nums[childpos]:
nums[pos] = nums[childpos]
pos = childpos
childpos = pos * 2 + 1
else:
break
nums[pos] = newitem
# 递归写法
def adjust_heap(nums, startpos, endpos):
pos = startpos
chilidpos = pos * 2 + 1
if chilidpos < endpos:
rightpos = chilidpos + 1
if rightpos < endpos and nums[rightpos] > nums[chilidpos]:
chilidpos = rightpos
if nums[chilidpos] > nums[pos]:
nums[pos], nums[chilidpos] = nums[chilidpos], nums[pos]
adjust_heap(nums, pos, endpos)
n = len(nums)
# 建堆
for i in reversed(range(n // 2)):
adjust_heap(nums, i, n)
# 调整堆
for i in range(n - 1, -1, -1):
nums[0], nums[i] = nums[i], nums[0]
adjust_heap(nums, 0, i)
return nums
八、计数排序
def counting_sort(nums):
if not nums: return []
n = len(nums)
_min = min(nums)
_max = max(nums)
tmp_arr = [0] * (_max - _min + 1)
for num in nums:
tmp_arr[num - _min] += 1
j = 0
for i in range(n):
while tmp_arr[j] == 0:
j += 1
nums[i] = j + _min
tmp_arr[j] -= 1
return nums
九、桶排序
def bucket_sort(nums, bucketSize):
if len(nums) < 2:
return nums
_min = min(nums)
_max = max(nums)
# 需要桶个数
bucketNum = (_max - _min) // bucketSize + 1
buckets = [[] for _ in range(bucketNum)]
for num in nums:
# 放入相应的桶中
buckets[(num - _min) // bucketSize].append(num)
res = []
for bucket in buckets:
if not bucket: continue
if bucketSize == 1:
res.extend(bucket)
else:
# 当都装在一个桶里,说明桶容量大了
if bucketNum == 1:
bucketSize -= 1
res.extend(bucket_sort(bucket, bucketSize))
return res
十、基数排序
def Radix_sort(nums):
if not nums: return []
_max = max(nums)
# 最大位数
maxDigit = len(str(_max))
bucketList = [[] for _ in range(10)]
# 从低位开始排序
div, mod = 1, 10
for i in range(maxDigit):
for num in nums:
bucketList[num % mod // div].append(num)
div *= 10
mod *= 10
idx = 0
for j in range(10):
for item in bucketList[j]:
nums[idx] = item
idx += 1
bucketList[j] = []
return nums
本题题解
代码
class Solution:
def sortArray(self, nums: List[int]) -> List[int]:
# 快速排序
if len(nums)<=1:
return nums
else:
pivot = nums[0]
less = [x for x in nums[1:] if x<pivot]
greater = [x for x in nums[1:] if x>=pivot]
return self.sortArray(less) + [pivot] +self.sortArray(greater)