遍历两轮,每两个前后比较,大的放到后面。exchange:当一轮中一次都没有交换的时候提前结束遍历。
def bubble_sort(self, li): # 冒泡排序
for i in range(len(li)):
exchange = False
for j in range(len(li) - i - 1):
if li[j] > li[j+1]:
li[j], li[j+1] = li[j+1], li[j]
exchange = True
if not exchange:
return li
遍历,选择最小的,放到列表第一个,以此类推。
def select_sort_simple(self, li): # 选择排序
li_new = []
for i in range(len(li)):
min_val = min(li)
li_new.append(min_val)
li.remove(min_val)
return li_new
遍历,从头把依次将小的值插入到大的值前面。
def insort_sort(self, li): # 插入排序
for i in range(1, len(li)):
tmp = li[i]
j = i - 1
while j >= 0 and li[j] > tmp:
li[j+1] = li[j]
j -= 1
li[j+1] = tmp
return li
找到中间值,小的都放该值左边,大的都放右边。递归。
先选取最左边的值为tmp, right只要比tmp大就左移直到找到比tmp小的,把right的值给left, left同理,left把当前值给right, 然后tmp把值给到当前的left。
def quick_sort(self, li, left, right): # 快速排序
if left < right:
mid = self.partition(li, left, right)
self.quick_sort(li, left, mid)
self.quick_sort(li, mid + 1, right)
return li
def partition(self, li, left, right):
tmp = li[left]
while left < right:
while left < right and li[right] >= tmp:
right -= 1
li[left] = li[right]
while left < right and li[left] <= tmp:
left += 1
li[right] = li[left]
li[left] = tmp
return left
先分再合,合的时候把小的放前面。li[low: high + 1] = res 里面+1是因为顾前不顾后。
def merge_sort(self, li, low, high): # 归并
if low < high:
mid = (low + high) // 2
self.merge_sort(li, low, mid)
self.merge_sort(li, mid + 1, high)
self.merge(li, low, mid, high)
return li
def merge(self, li, low, mid, high):
res = []
i = low
j = mid + 1
while i <= mid and j <= high:
if li[i] <= li[j]:
res.append(li[i])
i += 1
else:
res.append(li[j])
j += 1
while i <= mid:
res.append(li[i])
i += 1
while j <= high:
res.append(li[j])
j += 1
li[low: high + 1] = res
按一个区间不断排序,不断缩小区间。
def shell_sort(self, li):
d = len(li) // 2
while d > 1:
self.insert_sort_gap(li, d)
d = d // 2
return li
def insert_sort_gap(self, li, gap):
for i in range(gap, len(li)):
tmp = li[i]
j = i - gap
while j >= 0 and li[j] > tmp:
li[j + gap] = li[j]
j = j - gap
li[j + gap] = tmp
已知列表中的数范围在0到100之间。创建列表记录每个数字有几个,用enumerate把序号做了数字append到列表中。
def count_sort(li, max_count=100):
count = [0 for _ in range(max_count + 1)]
for val in li: # val是序列里的值
count[val] += 1
li.clear()
for val, ind in enumerate(count): # 值为val的元素有ind个
for i in range(ind):
li.append(val)
def bucket_sort(li, n=100, max_num=10000):
buckets = [[] for _ in range(n)] # 创建桶
for val in li:
i = min(val // (max_num // n), n - 1) # i表示val放到几号桶里
buckets[i].append(val)
# 可以全都放到桶里再排序,也可以放到桶里的过程中顺便排序
# 这里选第二种
for j in range(len(buckets[i]) - 1, 0, -1): # 从后往前遍历
if buckets[i][j] < buckets[i][j - 1]:
buckets[i][j], buckets[i][j - 1] = buckets[i][j - 1], buckets[i][j]
else:
break
sorted_li = []
for buc in buckets:
sorted_li.extend(buc) # 连接列表
return sorted_li
根据数字的位数将列表里的数分为几部分,对这几部分分别进行排序(和桶排序差不多)
def radix_sort(li):
max_num = max(li) # 最大值的位数
it = 0 # 迭代次数
while 10 ** it <= max_num:
buckets = [[] for _ in range(10)]
for val in li:
digit = (val // 10 ** it) % 10
buckets[digit].append(val)
# 分桶完成
li = []
for buc in buckets:
li.extend(buc)
# 把数写回li
it += 1
return li