[学习笔记] 数据结构与算法排序

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


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值