目录
前言:
写的程序肯定还可以优化,但是主要是实现功能,算法优化应该就是数学上的问题,暂不处理
如果逻辑看不懂可以上看这个网站:https://visualgo.net/zh(有图解)
排序
冒泡排序
# 冒泡排序
'''
逻辑:
比较相邻的两个元素。如果第一个比第二个大则交换他们的位置(升序排列,降序则反过来)。
从列表的开始一直到结尾,依次对每一对相邻元素都进行比较
从每个位置开始都要比较一轮
'''
array = [1, 2, 5, 4, 71, 3, 9, 6, 15, 2]
for i in range(len(array) - 1):
# 每经历一轮,每轮中就有i个元素排列好
mark = 0 # 标记为0就说明已经排列好
for j in range(len(array) - 1 - i):
if array[j] > array[j + 1]:
mark += 1
array[j], array[j + 1] = array[j + 1], array[j]
else:
continue
if not mark:
break
print(array)
选择排序
# 选择排序
'''
逻辑
1、 选取第一个元素,依次与后面元素进行比较,如果大于(小于)这个元素,就将二者位置交换,继续向后比较,直到最后一个元素
2、 重复比较每一个元素
'''
array = [1, 2, 5, 4, 7, 3, 9, 6, 15, 2]
for i in range(len(array) - 1):
for j in range(i + 1, len(array)):
if array[i] > array[j]:
array[i], array[j] = array[j], array[i]
else:
continue
print(array)
插入排序
# 插入排序
'''
逻辑:
1、将数组分为无序区和有序区
2、依次向无序区放入元素,要保证,放入元素时要放入合适的位置(即排好序)
3、直到将所有元素放入有序区就排序完成
'''
array = [1, 2, 5, 4, 7, 3, 9, 6, 15, 2]
for i in range(len(array)):
for j in range(i + 1):
if array[j] > array[i]:
array[j], array[i] = array[i], array[j]
print(array)
希尔排序
# 希尔排序
'''
希尔排序也就是 插入排序的升级版
因为插入排序对即将排好和元素数量较少的数组排序快,
所以需要对数组进行一些处理,使排序的速度加快,
而希尔排序就是解决这一问题的
逻辑
1、将数组内元素分组,开始以数组len的一半为步长,1与len + 1一组...等;
2、将每组内元素进行排序;
3、再以开始步长的一半为步长,进行分组排序...
4、到步长为1时,对数组排序也就是插入排序。
'''
def hill(array):
step = len(array) // 2 # 设置初始步长 分组
while step > 0: # 终止条件
for i in range(step, len(array)):
while i >= step and array[i] > array[i - step]: # 每组进行排序 当 i 小于步长时, 也就是到每组第一个元素,无需再比较啦
array[i], array[i - step] = array[i - step], array[i]
i -= step
step //= 2 # 缩短步长
return array
arr = [1, 2, 9, 5, 0, 10]
print(hill(arr))
快速排序
# 快速排序
'''
逻辑
1、 将第一个数的位置确定,保证这个数左边的小于(大于)它,右边的大于(小于)它
2、 在分别对左边右边里的数重复上面操作,直到剩最后一个数
伪代码:(从大到小)
首先,保存第一个数的值
在l小于r时:
首先先让右下标与第一个数的值比较
如果右下标大于第一个数的值
右下标向右移动一位
再次让右下标比较
否则
将右下标的值赋给左下标
接着让左下标与第一个数的值比较
如果左下标小于第一个数的值
左下标向左移动一位
再次让左下标比较
否则
将左下标的值赋给右下标
(到这里第一个数的位置已经确定)
将第一个数左边的进行排序
将第一个数右边的进行排序
:return
'''
def Quickpai(array, l, r): # array : 数组 l: 要排序的开始下标 r: 要排序的终止下标
if l >= r:
return array
end = r # 保存终止下标
# 由于Python交换两个变量的值无需借助其他变量,所以就没有保存第一个数的值
while l < r:
while l < r and array[r] >= array[l]:
r -= 1
array[l], array[r] = array[r], array[l]
while l < r and array[l] < array[r]:
l += 1
array[l], array[r] = array[r], array[l]
# 对第一个数左边进行排序
Quickpai(array, 0, l - 1)
# 对第一个数右边进行排序
Quickpai(array, l + 1, end)
array = [10, 2, 5, 4, 7, 3, 9, 6, 15, 2, 50, 24, 10, 0, 35]
Quickpai(array, 0, len(array) - 1)
print(array)
归并排序
# 归并排序
'''
逻辑
1、分组,将所有元素分成若干个含有2(1)个元素的组
2、每组元素进行排序
3、将小组两两合并
4、最终将所有组合并为初始的数组,排序完成
递归
'''
def merge(a, b):
c = []
h = j = 0
while j < len(a) and h < len(b): # 使用j、h确定分组内元素个数
if a[j] < b[h]:
c.append(a[j])
j += 1
else:
c.append(b[h])
h += 1
if j == len(a):
for i in b[h:]: # 如果一个分组内元素都已经存入c中,则另一个直接存入
c.append(i)
else:
for i in a[j:]:
c.append(i)
return c
def merge_sort(lists):
middle = len(lists) // 2
if len(lists) <= 1:
return lists
left = merge_sort(lists[:middle])
right = merge_sort(lists[middle:])
return merge(left, right)
a = [14, 2, 34, 43, 21, 19, 1, 9]
print(merge_sort(a))
计数排序
# 计数排序
'''
逻辑
1、 找出最大值与最小值
2、 统计最大值与最小值之间每一个数的个数
3、 依次将每个数存入列表,个数为几,则每个元素存几个
'''
arr = [1, 2, 0, 6, 5, 7, 4, 7, 3, 9, 10, 10, 2, 5, 7, 9, 6]
# 找出最大值和最小值
def Limit(array):
count = [] # 存放每个元素个数
max = arr[0]
min = arr[0]
for ar in arr:
if max < ar:
max = ar
if min > ar:
min = ar
# 统计每个元素的个数
for i in range(min, max + 1):
number = 0
for ar in arr:
if ar == i:
number += 1
count.append(number)
return count, min
# 将元素依次存入arr中
def Save(count, min):
new_arr = []
for c in count:
for i in range(0, c):
new_arr.append(min)
min += 1
return new_arr
print(Save(Limit(arr)[0], Limit(arr)[1]))
基数排序
# 基数排序
'''
逻辑 (使用二维数组进行实现更容易理解)
1、 分10个桶 0 - 9
2、 根据个位数向桶中放元素(如果个位数等于桶号)
3、 依次按照桶顺序将元素取出(取出顺序不作要求)
4、 根据十位数向桶中放数据(如果十位数等于桶号)
5、 依次按照桶顺序将元素以先进先出取出
'''
# 个位放 按放入桶的顺序取数据
def ge_in(array):
ge_arr = [i for i in range(0, 10)]
# 保存数组
save_arr = []
for ge in ge_arr:
for arr in array:
if ge == arr % 10:
save_arr.append(arr)
return save_arr
# 十位数
def shi_in(array):
shi_arr = [i for i in range(0, 10)]
# 保存数组
save_arr = []
for shi in shi_arr:
for arr in array:
if shi == arr // 10:
save_arr.append(arr)
return save_arr
if __name__ == "__main__":
arr = [2, 21, 15, 30, 42, 0, 11, 16, 19]
arr = ge_in(arr)
arr = shi_in(arr)
print(arr)
桶排序
# 桶排序
'''
最快:每个桶内元素一样时
最慢:所有元素在一个桶内
在空间允许下,桶越多速度越快
逻辑
每个桶内元素只有一个:
1、创建一个(最大值-最小值)大小的数组,每个元素都是0
2、如果对应的位置有元素,则让该位置元素加1
3、依次判断数组内的该元素是否为0,不为0则输出对应的值,再将该元素减1
每个桶内只有一个元素(与直接对数组进行排序差不多,排序时使用其他排序...)
每个桶内有多个元素:
1、创建一个(最大值-最小值)/n 向上取整大小的数组(这样采取二维数组进行更为方便)每个元素均为一个数组
2、数组的每个元素数组代表的则是上一个元素的最大值+1 - 最小值 + (元素下表 + 1) * 3,第一个数组开头则是最小值。依次将所以元素放入对应的元素数组中
3、对每个元素数组内元素进行排序(排序方法可自己随意选取)
4、依次输出所有元素
'''
import random
# 每个桶内元素只有一个
def BucketPai(arrs):
# 找出最大与最小值
min = max = arrs[0]
for arr in arrs:
if arr > max:
max = arr
elif arr < min:
min = arr
# 记录每个元素的个数
result_arr = []
for i in range(min, max + 1):
number = 0 # 记录个数
for arr in arrs:
if arr == i:
number += 1
result_arr.append(number)
# 将每个元素按照个数依次存入结果数组
result = []
for number in result_arr:
for num in range(number):
result.append(min)
min += 1
return result
if __name__ == "__main__":
arr = [random.randint(1, 666) for i in range(666)]
result = BucketPai(arr)
print(result)
如内容有误,还望提醒。