【练习】排序算法

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))

排序过程:

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值