跟b站up主学习数据结构与算法的代码笔记
视频链接:https://www.bilibili.com/video/BV1mp4y1D7UP
代码涵盖了基本的一些排序算法
包括:冒泡、选择、插入、快速、堆排序、桶排序、归并排序、希尔排序、ji计数、基数排序
import numpy as np
# 冒泡排序Bubble sort
def bubble_sort(li):
for i in range(len(li)-1):
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=np.random.randint(1,1000,500)
# print(li)
# bubble_sort(li)
# print(li)
# 选择排序
def select_sort(li):
for i in range(len(li)-1):
min_loc = i
for j in range(i+1,len(li)):
if li[j] < li[min_loc]:
min_loc=j
li[i],li[min_loc] = li[min_loc],li[i]
# 插入排序
def insert_sort(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
# li=[3,2,4,1,5,7,9,6,8]
# insert_sort(li)
# print(li)
# 快速排序
def partition(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
def quick_sort(li,left,right):
if left<right:
mid=partition(li,left,right)
quick_sort(li,left,mid-1)
quick_sort(li,mid+1,right)
# li=[5,7,4,6,3,1,2,9,8]
# quick_sort(li,0,len(li)-1)
# 堆排序
def sift(li,low,high):
"""
:param li:列表
:param low:堆的根节点位置
:param high:堆的最后一个元素位置
:return:
"""
i = low
j = 2*i + 1
tmp = li[low]
while j <= high:
if j+1 <= high and li[j+1] > li[j]:
j = j + 1
if li[j] > tmp:
li[i] = li[j]
i = j
j = 2 * i + 1
else:
li[i] = tmp
break
else:
li[i] = tmp
def heap_sort(li):
n=len(li)
for i in range((n-2)//2,-1,-1):
# i表示建堆的时候调整的部分的根的下标
sift(li,i,n-1)
# 建堆完成
print(li)
for i in range(n-1,-1,-1):
# i指向当前堆的最后一个元素
li[0],li[i]=li[i],li[0]
sift(li,0,i-1)
'''
## 内置函数heapq堆函数
import heapq
import random
li=list(random(100))
random.shuffle(li)
print(li)
heapq.heapify(li) # 建堆
n=len(li)
for i in range(n):
print(heapq.heappop(li),end=',')
'''
# 堆排序--topk问题
# 现有n个数,设计算法得到前k大的数(k<n)
# 解决思路:
# 排序后切片 O(nlogn)
# 排序lowb三人组 O(mn)
# 堆排序思路 O(nlogk)
def sift(li,low,high):
"""
:param li:列表
:param low:堆的根节点位置
:param high:堆的最后一个元素位置
:return:
"""
i = low
j = 2*i + 1
tmp = li[low]
while j <= high:
if j+1 <= high and li[j+1] < li[j]:
j = j + 1
if li[j] < tmp:
li[i] = li[j]
i = j
j = 2 * i + 1
else:
li[i] = tmp
break
else:
li[i] = tmp
def topk(li,k):
heap=li[0:k]
for i in range((k-2)//2,-1,-1):
sift(heap,i,k-1)
# 1.建堆
for i in range(k,len(li)-1):
if li[i]>heap[0]:
heap[0]=li[i]
sift(heap,0,k-1)
# 2.遍历
for i in range(k-1,-1,-1):
# i指向当前堆最后一个元素
heap[0],heap[i]=heap[i],heap[0]
sift(heap,0,i-1) # i-1是新的high
# 3.出数
return heap
# import random
# li=list(range(1000))
# random.shuffle(li)
# print(topk(li,k=10))
# 归并排序
# 要求列表分两段有序
def merge(li,low,mid,high):
i = low
j = mid + 1
ltmp = []
while i <= mid and j <= high: # 只要两边都有数
if li[i] < li[j]:
ltmp.append(li[i])
i += 1
else:
ltmp.append(li[j])
j += 1
# while执行完,肯定有一部分没数
while i <= mid:
ltmp.append(li[i])
i += 1
while j <= high:
ltmp.append(li[j])
j +=1
li[low:high+1]=ltmp
# li=[2,4,5,7,1,3,6,8]
# merge(li,0,3,7)
# print(li)
def merge_sort(li,low,high):
if low < high:
mid = (low + high) // 2
merge_sort(li,low,mid)
merge_sort(li,mid+1,high)
merge(li,low,mid,high)
# li=list(range(10))
# import random
# random.shuffle(li)
# print(li)
# merge_sort(li,0,len(li)-1)
# print(li)
# 希尔排序
def insert_sort_gap(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 -= gap
li[j+gap] = tmp
def shell_sort(li):
d=len(li) // 2
while d >= 1:
insert_sort_gap(li,d)
d //= 2
# import random
# li=list(range(1000))
# random.shuffle(li)
# shell_sort(li)
# print(li)
# 计数排序
def count_sort(li,max_count=100):
count=[0 for _ in range(max_count+1)]
for val in li:
count[val] +=1
li.clear()
for ind,val in enumerate(count):
for i in range(val):
li.append(ind)
# import random
# li=[random.randint(0,100) for _ in range(1000)]
# print(li)
# count_sort(li)
# print(li)
# 桶排序
def bucket_sort(li,n=100,max_num=10000):
buckets=[[] for _ in range(n)] # 创建桶
for var in li:
i=min(var//(max_num//n),n-1) # i 表示var放到几号桶内
buckets[i].append(var) # 把var加到桶里边
# 保持桶内顺序
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
# import random
# li=[random.randint(0,10000) for i in range(100000)]
# li=bucket_sort(li)
# print(li)
# 基数排序
def radix_sort(li):
max_num=max(li)
it=0
while 10 ** it <= max_num:
buckets=[[] for _ in range(10)]
for var in li:
digit=(var//10 ** it) % 10
buckets[digit].append(var)
# 分桶完成
li.clear()
for buc in buckets:
li.extend(buc)
# 把数重新写回li
it += 1
# import random
# li=list(range(100))
# random.shuffle(li)
# radix_sort(li)
# print(li)