Python实现8大排序算法

8大算法:冒泡排序,选择排序,插入排序,快速排序,堆排序,归并排序,哈希排序,桶排序(未实现)

制造一个计数器和模拟个无序列表:

# 计时器:
import time
def cal_time(func):
    def wapper(*args,**kwargs):
        start_time = time.time()
        result = func(*args,**kwargs)
        end_time = time.time()
        print("%s running time is %s s:" %(func.__name__,end_time-start_time))
        return result
    return wapper
# 造一个无序数列
import random
data = list(range(100))
random.shuffle(data)
print(data)

1、冒泡排序:

# 冒泡
@cal_time
def bubble_sort(li):
    for i in range(len(li) - 1):
        for j in range(len(li) - i - 1):
            if li[j] > li [j+1]:
                li[j],li[j+1] = li[j+1],li[j]
bubble_sort(data)
print(data)

​

​

冒泡优化:如果执行过程中执行一趟后,发现没有改变,则说明已经排好序了,无序在进行后面的排序,直接结束

@cal_time
def bubble_sort1(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:
            break
bubble_sort1(data)
print(data)

2、选择排序:找出最小的和前面依次换

@cal_time
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]
select_sort(data)
print(data)

3、插入排序:在无序列表里依次取出在有序列表里插入

@cal_time
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 = j-1
        li[j+1] = tmp
insert_sort(data)
print(data)

4、快速排序 :时间复杂度为O(nlogn),最坏情况为O(n^2)(就是反向排序,永远不会把列表分成两块)

思想:

① 取一个元素(第一个元素),使其归位;

② 列表被分成两半,左边的都比他小,右边的都比他大;

③ 递归完成排序

# 递归
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)
# 排序
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
@cal_time
def quick_sort_1(li):
    return quick_sort(data,0,len(data)-1)
quick_sort_1(data)
print(data)

5、堆排序:

思想:

① 建立堆;

② 得到堆顶元素,为最大元素;

③ 去掉堆顶,将最后一个元素放到堆顶,通过一次调整使堆有序;

④ 堆顶元素为第二大元素;

⑤ 直到堆变空

知识点:

完全二叉树,满二叉树

父节点和左孩子节点:i~2*i+1

父节点和右孩子节点:i~2*i+2

最后一个父节点:n//2-1

# 堆排序调整过程:
def shift(li,top,last):
    i = top     # 父节点
    tmp = li[i]
    j = 2 * i + 1 # 左孩子节点
    while j <= last :
        if j < last and li[j] < li[j+1]: #如果存在右孩子节点,则进行右孩子节点的排序
            j = j + 1
        if li[j] > tmp : # 如果左孩子节点比父节点大,则换位置
            li[i] = li[j] # 孩子节点的值放到父节点
            i = j         # 新的父节点
            j = 2 * i + 1 # 新的孩子节点
        else:
            break
    li[i] = tmp
# 取出堆顶排序:
@cal_time
def heap_sort(li):
    n = len (li)
    for i in range(n//2-1, -1 ,-1): # 从最后一个父节点开始
        shift(li,i,n-1)
    
    # 比较省内存的写法
    for i in range(n-1, -1 ,-1): # 将堆顶最大元素和最后一个元素互换,继续排序
        li[0],li[i] = li[i],li[0] # 将栈顶元素存到最后一个元素,最后一个元素不加入堆,为了节省内存
        shift(li,0,i-1)
    # # 占用一点内存的写法:使用一个空列表appe堆顶元素
    # sult_list = []
    # for i in range(n-1,-1,-1):
    #     sult_list.append(li[0])
    #     li[0] = li[i]
    #     shift(li,0,i-1)
    # print(sult_list)
heap_sort(data)
print(data)

6、归并排序 : 时间复杂度 O(nlogn)

思想:

① 先分解:将一个列表分解成单个元素

② 比较,形成两个有序列表

③ 合并,将两个有序列表归并

# 合并,将两个有序的列表合并
def merge(li,low,mid,high):
    i = low
    j = mid + 1
    tmp = []
    while i <= mid and j <= high:
        if li[i] < li[j]:
            tmp.append(li[i])
            i += 1
        else:
            tmp.append(li[j])
            j += 1
    while i <= mid:
        tmp.append(li[i])
        i += 1
    while j <= high:
        tmp.append(li[j])
        j += 1
    li[low:high+1] = tmp
# 测试merge():
'''
testList = [1,3,5,6,2,4,8,9]
merge(testList,0,3,7)
print(testList)
'''
# 分解合并成两个有序列表
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)  # 输出两个有序列表  
@cal_time
def merge_sort_1(li):
    merge_sort(data,0,len(data)-1)
merge_sort_1(data)
print(data)

7、希尔排序

思想:

① 将列表按len(list)//2,分成len(list)//2个列表

② 将每个列表进行排序

③ 将每个列表各取一个一个插入,整合成一个新的列表

④ 再将新的列表按 (len(list)//2)//2,再分,再合并

⑤ 最后分成一个列表,进行插入排序

@cal_time
def shell_sort(li):
    gap = len(li) // 2
    while gap > 0 :
        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
        gap //= 2
shell_sort(data)
print(data)

8、桶排序:

桶排序也叫计数排序,

就是将数据集里面所有元素按顺序列举出来,然后统计元素出现的次数。最后按顺序输出数据集里面的元素。

本人觉得这个快是快,但是太耗内存,就没有实现。。。。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值