python实现数据结构八种排序算法

本文作为本人笔记之用,转载请注明出处!

 

一、冒泡排序

def bubble_sort(lis):
    '''时间复杂度最低的冒泡排序'''
    n = len(lis)
    for i in range(n):
        print(f'第{i}次----->{lis}')
        exchange = False
        for j in range(n-i-1):
            if lis[j] > lis[j+1]:
                lis[j],lis[j+1] = lis[j+1],lis[j]
                exchange = True  # 表示发生了交换
        if exchange == False:
            break
lis = [1,9,2,8,3,6,4,5,7]
print('排序前:',lis)
bubble_sort(lis)
print('排序后:',lis)

 

二、选择排序

def select_sort(lis):
    n = len(lis)
    for i in range(n):
        print(f'第{i}次----->{lis}')
        min_loc = i   # 此轮最小的元素的索引,先默认当前元素的索引
        for j in range(i+1,n):
            if lis[j] < lis[min_loc]:
                min_loc = j

        lis[i],lis[min_loc] = lis[min_loc],lis[i]

lis = [1,9,2,8,3,6,4,5,7]
print('排序前:',lis)
select_sort(lis)
print('排序后:',lis)

 

三、插入排序

def insert_sort(lis):
    n = len(lis)
    for i in range(1,n):   # 默认手上有第一张牌
        print(f'第{i}次----->{lis}')

        # 无序区(牌堆)拿到当前第一张牌(第i次抓第i张牌)
        tmp = lis[i]

        # 有序区(手上牌)最后一张牌的位置
        j = i - 1    # j表示i的前一个元素
        while lis[j] > tmp and j >= 0:  # 判断前一个元素是否比当前元素(lis[i])大
            lis[j+1] = lis[j]     # j+1 等价于 i的位置,即把索引为j的元素往后移一位
            j -= 1   # 往左边移一位
        lis[j+1] = tmp

lis = [1,9,2,8,3,6,4,5,7]
print('排序前:',lis)
insert_sort(lis)
print('排序后:',lis)

 

四、快速排序

def partition(data,left,right):
    # left是左边指针,right是右边指针
    tmp = data[left]
    while left < right:
        while left < right and data[right] >= tmp:
            right -= 1
        data[left] = data[right]

        while left < right and data[left] <= tmp:
            left += 1
        data[right] = data[left]

    # 最后指针重合的位置就是tmp的最终位置,left/right都行
    data[left] = tmp
    # 返回left/right的位置
    return left

def quick_sort(lis,left,right):
    if left < right:
        mid = partition(lis,left,right)
        quick_sort(lis,left,mid-1)  # mid位置的左边递归
        quick_sort(lis,mid+1,right)  # mid位置的右边递归

def quick_sort_s(lis):
    return quick_sort(lis,0,len(lis)-1)

lis = [1,9,2,8,3,6,4,5,7]
print('排序前:',lis)
# quick_sort(lis,0,8)
quick_sort_s(lis)
print('排序后:',lis)

 

五、归并排序

def merge(left_lis,right_lis):
    l_loc = 0
    r_loc = 0
    result = []
    while l_loc < len(left_lis) and r_loc < len(right_lis):
        if left_lis[l_loc] < right_lis[r_loc]:
            result.append(left_lis[l_loc])
            l_loc += 1
        else:
            result.append(right_lis[r_loc])
            r_loc += 1

    result += left_lis[l_loc:]
    result += right_lis[r_loc:]

    return result

def merge_sort_s(lis):
    if len(lis) <= 1:  # 递归结束条件
        return lis
    # 二分分解
    num = len(lis)//2
    left_lis = merge_sort_s(lis[:num])
    right_lis = merge_sort_s(lis[num:])

    # 归并
    return merge(left_lis,right_lis)

lis = [3,4,54,3,2,3,44,5]
print('排序前:')
print(lis)
lis = merge_sort_s(lis)
print('排序后:')
print(lis)

 

六、希尔排序

def  shell_sort(lis):
    n = len(lis)

    # 初始步长(即分多少组,步长要逐渐减少)
    gap = n//2

    while gap > 0:
        print(f'gap:{gap}'.center(50,'-'))
        print(lis)

        for i in range(gap,n):
            j = i
            while j >= gap and lis[j-gap] > lis[j]:
                lis[j-gap], lis[j] = lis[j], lis[j-gap]
                j -= gap

        # 每一次步长是上一次的一半
        gap = gap // 2

lis = [7,5,4,6,3,8,2,9,1]
print('排序前:')
print(lis)
print('')
shell_sort(lis)
print('排序后:')
print(lis)

 

七、堆排序

def sift(data,low,finally_loc):
    # finally_loc是最后一个元素的索引
    i = low      # low是最后一个元素的父节点
    j = 2*i + 1  # 最后一个元素(左节点),或者最后一个元素的兄弟节点(左节点)

    # 不知道是否是称职的领导
    tmp = data[i]

    # 判断是否称职
    while j <= finally_loc:   # 防止越界
        # 找到孩子节点中的最大值
        if j < finally_loc and data[j] < data[j+1]:  # 如果左节点比右节点小
            j += 1 # j定位到孩子节点中较大者的位置

        # 判断是否称职
        if tmp < data[j]:  # 如果不称职
            data[i] = data[j]  # 孩子节点上位
            i = j  # 孩子的位置空了,其位置变成新的i(将要竞争的领导位置)
            j = 2 * i +1   # 新的竞争的位置的左节点
        else:  # 如果称职
            break

    data[i] = tmp


def sift_sort(data):
    n = len(data)
    for i in range(n//2-1,-1,-1):  # n//2-1  一定是最后一个元素的父节点
        sift(data,i,n-1)  # 构造大根堆

    # 挨个出数
    for i in range(n-1,-1,-1):   # 根要存放的位置,从最后一个位置向前倒数
        data[i],data[0] = data[0],data[i]  # 根和要存放的位置互换,互换以后不再是堆,需要向下调整
        sift(data,0,i-1)

lis = [7,5,4,6,3,8,2,9,1]
print('排序前:',lis)
sift_sort(lis)
print('排序后:',lis)

 

八、桶排序

def bucket_sort(lis):
    # 构造桶
    buckets = [0] * (max(lis)-min(lis)+1)

    for i in range(len(lis)):
        buckets[lis[i]-min(lis)] += 1

    # 出数
    res = []
    for i in range(len(buckets)):
        if buckets[i] != 0:
            # [i + min(lis)]:桶所代表的元素,buckets[i]:桶里面的次数
            res += [i + min(lis)] * buckets[i]

    return res

lis = [1,9,2,8,3,6,4,5,7]
print('排序前:',lis)
lis = bucket_sort(lis)
print('排序后:',lis)

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值