10种排序算法:
1.冒泡排序 (√)
2.选择排序(√)
3.插入排序(√)
4希尔排序(√)
5归并排序(√)
6快速排序(√)
7堆排序(⍻)
8计数排序(√)
9桶排序(√)
10基数排序(√)
参考代码地址如下↓
开源项目地址:https://github.com/hustcc/JS-Sorting-Algorithm,整理人 hustcc。
GitBook 在线阅读地址:https://sort.hust.cc/
1.冒泡算法
#1.冒泡排序:两个两个数相互比较,然后小的往前放,最后形成有序的list
abc = [4,12,3,2,5]
def bubbleSort(num):
# N个数作比较 比较次数为N-1
for i in range(len(num)-1):
for j in range(len(num)-i-1):
if num[j] > num[j+1]:
num[j], num[j+1] = num[j+1], num[j]
print(num)
print("---------------")
bubbleSort(abc)
冒泡排序
def bubbleSort(num):
# N个数作比较 比较次数为N-1
for i in range(len(num)-1):
for j in range(len(num)-i-1):
if num[j] > num[j+1]:
num[j], num[j+1] = num[j+1], num[j]
return num
2.选择排序
#2.选择排序:先选择第一个数为最小值,然后往后寻找有无更小的数,没有则从剩余的数中寻找最小的元素,然后放到已排序的队尾
def selectionSort(num):
# 首先我们要先定义最小的索引值
for i in range(len(num) - 1):
minIndex = i
for j in range(i+1, len(num)):
# 判断是否为最小值 若不是则替换索引值
if num[j] < num[minIndex]:
minIndex = j
# 如果 索引值不再相同 证明需要交换数值
if i != minIndex:
num[i], num[minIndex] = num[minIndex], num[i]
return num
同样配图方便理解
3.插入排序
#3.插入排序:像扑克牌一样将手牌从小到大排好。
def insertionSort(num):
for i in range(len(num)):
preIndex = i-1
current = num[i]
while preIndex >= 0 and num[preIndex] > current:
num[preInex + 1] = num [preIndex]
preIndex -= 1
num[preIndex + 1] = current
return num
4.希尔排序
参考:https://chihokyo.com/post/14/
#希尔排序:插入排序的一种,通过步长(相距一定的间隔的元素来进行比较)
abc = [4,12,3,2,5,1]
def ShellSort(arr):
n = len(arr)
# 这里的gap取什么是根据你的实际状况取最优,为了展示方便,选择了取半
gap = n // 2
while gap > 0:
for i in range(gap,n):
j = i
while j > 0:
# 到这里就很插入有不一样的地方了,对比的不是-1,而是减去步长
if arr[j] < arr[j-gap]:
arr[j], arr[j-gap] = arr[j-gap], arr[j]
# 这里也是同理
j -= gap
else:
break
# 然后在进行分组 直到 while的gap不是为0为止
gap //= 2
return arr
print(ShellSort(abc))
5.归并排序
参考网站:
1.https://wenku.baidu.com/view/79db2628497302768e9951e79b89680203d86b00.html
2.https://github.com/hustcc/JS-Sorting-Algorithm/blob/master/5.mergeSort.md
3.https://www.bilibili.com/video/BV1et411N7Ac?spm_id_from=333.337.search-card.all.click&vd_source=80842c2980441ef6510d3aa2bad45785
# 归并排序
# 思路: 归并排序就是通过分组的方式将一个个的数字进行分组的结合,最终获得一个有序的数组,
def mergeSort(a):
mid = len(a) // 2 # 找到list的一半
if len(a) < 2: # 判断
return a
left = mergeSort(a[:mid]) # 通过递归将其左右排好序,再进行归并
right = mergeSort(a[mid:])
return merge(left, right)
def merge(left,right):
new = []
while left and right: # 当左和右只要有一个不为零时就执行(例如:while 0 是不执行的)
if left[0] <= right[0]: # 判断
new.append(left.pop(0)) # 将left的第一个数删除插入到新的list里面
else:
new.append(right.pop(0)) # right比left小,则将right插入到新的列表里面
"""以上一直循环到,一个list为空,则停止循环"""
""" 但list不一定都是正好平分,所以会有多出来的情况"""
while left:
new.append(left.pop(0))
while right:
new.append(right.pop(0))
return new
a= [2,1,3,4,10,5]
print(mergeSort(a))
6.快速排序
参考:1.https://www.bilibili.com/video/BV1LZ4y1T7Ty?spm_id_from=333.337.search-card.all.click&vd_source=80842c2980441ef6510d3aa2bad45785
2.https://blog.csdn.net/qq_51201337/article/details/123322027
# 快速排序
"""思想:首先创建一个pivot来为基准,若right小于pivot,将right放到pivot的位置,left大于pivot则将left放在刚才right的位置。
随后得到一个左边都是比pivot小的数,右边都是比pivot大的数。
"""
def quickSort(a, left, right):
if left < right: # 判断
mid = partition(a, left, right) # 开始快排,用于交换left和right的位置
quickSort(a, mid+1, right) # left小于pivot,指针+1,往后移一个单位
quickSort(a, left, mid-1) # right大于pivot,指针-1,往前移一个单位
def partition(a, left, right):
pivot = a[left] # 定义基准pivot
while left < right: # 当left逐渐增大,right逐渐减小
while left < right and a[right] >= pivot: # 从右边开始找一个比pivot小的数,没有则right-1 继续往下找
right -= 1
a[left] = a[right] # 找到之后将right的值赋予left
while left < right and a[left] <= pivot: # 从左边开始找比pivot大的值将其放到右边。
left += 1
a[right] = a[left]
a[left] = pivot # 当left大于right时,证明左右数字都已经交换完毕,将pivot基准放在a[left]处,代表完成一次排序
return left
a = [3, 4, 6, 1, 2, 5]
print("befor quickSort:", a)
quickSort(a, 0, len(a)-1)
print("after quickSort:", a)
7.堆排序
参考:https://www.jianshu.com/p/d174f1862601
# 堆其实是一种树结构
# 堆排序(区分大顶堆和小顶堆)
"""节点下标为i 左子节点下标为 2i+1 右子节点下标为2i+2
思路:
1.先进行大根堆
2.然后将顶点与尾结点进行交换,将顶点弹出堆中
3.再将剩余的进行大根堆的创建,然后再循环重复
4.最后直到堆中没有数字,序列创建完成
"""
from collections import deque
a = deque([3, 10, 21, 15, 80, 1, 70, 60])
a.appendleft(0)
def heapSort(a):
length = len(a) - 1 # 因为引入了一个辅助空间0
firstSort = length // 2 # 找出所有有孩子的最后一个树的序列
"""进行把序列调整为一个大根堆"""
for i in range(firstSort):
heap_adjust(a, firstSort - i, length)
"""把堆顶元素和末尾元素交换,把剩下元素调整为一个大根堆"""
for i in range(length - 1):
a = swap(a, 1, length - i)
heap_adjust(a, 1, length - i - 1)
return [a[i] for i in range(1,len(a))]
def swap(a, i, j):
a[i], a[j] = a[j], a[i]
return a
"""用于调整树内的大小值"""
def heap_adjust(a, start, end):
temp = a[start] # 用于存放start的数值
i = start # 确定i节点
j = 2 * i # 确定j为i的子节点
while j <= end: # 判断
if(j < end) and (a[j] < a[j+1]):
j += 1
if temp < a[j]:
a[i] = a[j] # 交换值,便结束进入下一棵树
i = j # 所以i从4变为8
j = 2 * i
else:
break
a[i] = temp #使交换完后的
print(heapSort(a))
8.计数排序(遇到大数内存爆炸版)
参考:https://blog.csdn.net/weixin_43790276/article/details/107398262
# 思路:首先我们先计算出最大数值 然后创建一个count 来存放这些数字出现的次数,
# 然后我们遍历数组,将出现的次数+1.创建新数组,然后依次循环将数字加入新的数组中,最后完成排序
def counting_Sort(arr):
max_num = max(arr)
count = [0] * (max_num+1)
for i in arr:
count[i] += 1
new_arr = list()
for i in range(len(count)):
for j in range(count[i]):
new_arr.append(i)
return new_arr
print(counting_Sort(a))
9.桶排序
参考:https://blog.csdn.net/qq_52253798/article/details/122970542
#桶排序
#思路:首先定义0-9 10个桶, 遍历数组 然后将最高位数的数字放在对应的桶里
#最后将其依次弹出
a = [1, 45, 32, 23, 22, 31, 47, 24, 4, 15, 99,87,65]
def bucketSort(arr):
bucket = [[] for i in range(10)]
# for i in range(len(bucket)):
# bucket[i] = int
for i in range(len(arr)): #循环
index = arr[i] // 10 # 得到bucket下标
bucket[index].append(arr[i]) #将得到的数字加入bucket中
coll = []
for i in range(len(bucket)):
bucket[i].sort()
print(bucket) # 已经得到排好后的bucket了,接下来需要将其依次取出放入一个新的list里,并用arr 继承就ok
for i in bucket:
for j in i:
coll.append(j)
arr = coll
return arr
print(bucketSort(a))
10.基数排序
参考:https://github.com/hustcc/JS-Sorting-Algorithm/blob/master/10.radixSort.md
#
# 基数排序
# 个位 = num % 10 ;十位 = num // 10 % 10;百位 = num // 100 % 10;千位 = num // 1000
# a = [10, 17, 50, 7, 30, 24, 27, 45, 15, 5, 36, 21]
def radix(arr):
digit = 0 # 最小位数个位
max_digit = 1 #先定一个位数1
max_value = max(arr) # 得到最大的数值 max_value = 50
# 找出列表中最大的位数
while 10 ** max_digit < max_value: # 需要确定最大数的位数 10 < 50
max_digit = max_digit + 1 # max_digit = 2 也就是两位数
while digit < max_digit: # 0 < 2
print("digit:", digit)
temp = [[] for i in range(10)] # temp = [0,1,2,3,4,5,6,7,8,9]
for i in arr: # 遍历数组
# 求出每一个元素的个、十、百位的值
t = int((i / 10 ** digit) % 10) # 先计算10的次方再算i除以10的次方的结果
temp[t].append(i)
print("i:", i, temp)
coll = [] # 新建一个空列表
for bucket in temp: # 从桶里面拿输出来(bucket)
for i in bucket:
coll.append(i)
print("coll:", coll)
arr = coll
digit = digit + 1
return arr
a = [10, 17, 50, 7, 30, 24, 27, 45, 15, 5, 36, 21]
print(radix(a))
排序过程: