【代码实战】大话数据结构4:排序部分 Python 代码实现

因本人最近在恶补数据结构,学识经验有限,如有不正之处望读者指正,不胜感激;也望借此平台留下学习笔记以温故而知新。这一篇博客主要是最近刚开始接触大话数据结构一书,写的通俗易懂,很多图表帮忙理解,所以讲随手笔记分享至此,希望对您有所帮助。

排序算法的 Python 实现

# -*- coding: utf-8 -*-
"""
Created on Mon Jun 22 22:57:43 2020

@author: yx
"""

def exchange_sort(L):
    '''
    函数功能:简单交换排序
    基本思想:内外循环,每趟循环一一比较数据并交换
    参数 L:待排序数据
    返回 L:完成排序的数据
    '''
    n = len(L)
    for i in range(n-1):
        for j in range(i+1, n):
            if L[i] > L[j]:
                L[i], L[j] = L[j], L[i]
    return L


def bubble_sort(L):
    '''
    函数功能:冒泡排序
    基本思想:内外循环,每次内循环从后向前比较,并将最大值放在末尾
    参数 L:待排序数据
    返回 L:完成排序的数据
    '''
    n = len(L)
    for i in range(n):
        for j in range(n-1, i, -1):
            if L[i] > L[j]:
                L[i], L[j] = L[j], L[i]
    return L 


def choose_sort(L):
    '''
    函数功能:简单选择排序
    基本思想:内外循环,找出外循环当次一一比较后的最值索引,每轮最多交换一次
    参数 L:待排序数据
    返回 L:完成排序的数据
    '''
    n = len(L)
    for i in range(n):
        min = i
        for j in range(i+1, n):
            if L[min] > L[j]:
                min = j
        if i != min:
            L[i], L[min] = L[min], L[i]
    return L
         

def insert_order(L):
    '''
    函数功能:直接插入排序
    基本思想:从第二个数开始循环,一一与外循当次数比较,小则插入其前,大则拼接其后
    参数 L:待排序数据
    返回 L:完成排序的数据
    '''
    n = len(L)
    for i in range(1, n):
        if L[i] < L[i-1]:
            temp = L[i]
            for j in range(i-1, -1, -1):
                if L[j] > temp:
                    L[j+1] = L[j]
                else:
                    break
                L[j] = temp       
    return L
         

def shell_order(L):
    '''
    函数功能:希尔排序
    基本思想:直接插入排序的升级,为了提升时间效率,将数据按照一定增量的子列逐步排序
    参数 L:待排序数据
    返回 L:完成排序的数据
    '''
    n = len(L)
    delta = n
    while(delta > 1):
        delta = int(delta/3)  + 1
        for i in range(delta, n):
            if L[i] < L[i-delta]:
                temp = L[i]
                for j in range(i-delta, -1, -delta):
                    if L[j] > temp:
                        L[j+delta] = L[j]
                    else:
                        break
                    L[j] = temp
    return L
        

def heap_function(L, i, n):
    '''
    函数功能:大顶堆构建
    参数 L:待排序数据
    参数 i:待排序数据根结点关键字索引
    参数 n:排序数据长度
    返回 L:完成排序的数据
    '''
    temp = L[i]
    s = 2*i + 1   
    while(s<n):
        j = s
        if j<(n-1) and L[j]<L[j+1]:
            j += 1
        if temp > L[j]:
            break
        L[i] = L[j]
        i = j 
        s = 2*s + 1
    L[i] = temp
    
    return L 
    
def heap_sort(L):
    '''
    函数功能:堆排序
    基本思想:简单选择排序的升级,将无序列表构造大顶堆,根结点和尾结点交换,剩余数据构造大顶堆
    参数 L:待排序数据
    返回 L:完成排序的数据
    '''
    # 原始数据表构建大顶堆
    n = len(L)
    bi_len = int(n/2)-1
    for i in range(bi_len, -1, -1):
        L = heap_function(L, i, n)
        
    # 数据交换位置,并将剩余数据构造大顶堆
    for i in range(n-1, 0, -1):
        L[0], L[i] = L[i], L[0]
        L = heap_function(L, 0, i)
    return L

           
  
def merge(L, i, m, n):
    '''
    函数功能:将两个有序的子列归并成一个有序列
    参数 L:待排序数据
    参数 i:归并开始的下标
    参数 m:划分小大两部分的下标索引
    参数 n:大数据两部分的最大索引
    返回 L_merge:完成排序的数据
    ''' 
    L_merge = list()
    j = m + 1
    while(i<=m and j<=n):
        if (L[i] < L[j]):
            L_merge.append(L[i])
            i += 1
        else:
            L_merge.append(L[j])
            j += 1
            
    delta_len = len(L) - len(L_merge)
    if (i<=m):
        for l in range(delta_len):
            L_merge.append(L[i + l])
    if (j<=n):
        for l in range(delta_len):
            L_merge.append(L[j + l])
    return L_merge  

def merge_function(L, s):
    '''
    函数功能:两两归并
    参数 L:待排序数据
    参数 s:归并序列长度
    返回 L_merge:排序完成的序列
    '''
    n = len(L) - 1
    k = 0
    L_merge = list()
    while(k<=n-2*s+1):
        L_sub = L[k:k+2*s]
        L_temp = merge(L_sub, 0, s-1, 2*s-1)
        k = k+2*s
        L_merge.extend(L_temp)
    
    if (k<(n+1)):
        for j in range(k,n+1):  
            L_merge.append(L[j])
    return L_merge

def merge_sort(L):
    '''
    函数功能:归并排序
    基本思想:待排数据看成某有多少数据的子序列,两两归并知道得到长度为n的有序数列
    参数 L:待排序数据
    返回 L_merge:完成排序的数据
    '''
    n = len(L)-1
    k = 1
    L_merge = L
    while((2*k)<=n):
        L_merge = merge_function(L_merge,k)
        k = 2*k
    if (k < (n+1)):
        L_merge = merge(L_merge, 0, k-1, n)
    return L_merge


def quick_function(L, low, high):
    '''
    函数功能:快排中划分数据集为大数据和小数据的节点 
    参数 L:待排序数据
    参数 low:数据列表最小下标
    参数 hight:数据列表最大下标
    返回 low:划分节点数据
    '''
    # 三数取中
    medium = low + int((high - low) / 2)
    if (L[low] > L[high]):
        L[low], L[high] = L[high], L[low]
    if (L[medium] > L[high]):
        L[medium], L[high] = L[high], L[medium]
    if (L[medium] > L[low]):
        L[medium], L[low] = L[low], L[medium]
    pivot = L[low]

    # 取根据划分数据的大小划分小于其数值的数据和大于其数值的数据
    while(low < high):
        while(low < high and L[high] >= pivot):
            high -= 1
        L[low], L[high] = L[high], L[low]

        while(low < high and L[low] <= pivot):
            low += 1
        L[low], L[high] = L[high], L[low]     
    return low

def quick_sort(L):
    '''
    函数功能:快排  
    基本思想:冒泡排序的升级,每趟循环将待排数据划分成比当前数据小和大的两部分
    参数 L:待排序数据
    返回 L:完成排序的数据
    '''
    # 快排过程循环划分
    def q_sort(L, low, high):
        if (low < high):
            pivot = quick_function(L, low, high)
            
            q_sort(L, low, pivot-1)
            q_sort(L, pivot+1, high)
        return L
            
    low = 0
    high = len(L) - 1
    L = q_sort(L, low, high)
    return L 


def main(L):
    '''
    函数功能:排序  
    参数 L:待排序数据
    返回 L:完成排序的数据
    '''
    # 堆排序
    heap_sort_list = heap_sort(L)
    print('堆排序结果是:', heap_sort_list)   
    
    # 简单交换排序
    exchange_sort_list = exchange_sort(L)
    print('简单交换排序结果:', exchange_sort_list)         

    # 冒泡排序
    bubble_sort_list = bubble_sort(L)
    print('冒泡排序结果是:', bubble_sort_list) 
    
    # 简单选择排序
    choose_sort_list = choose_sort(L)
    print('简单选择排序结果是:',choose_sort_list)   
    
    # 直接插入排序
    insert_order_list = insert_order(L)
    print('直接插入排序结果是:', insert_order_list)   
    
    # 希尔排序 
    shell_order_list = shell_order(L)
    print('希尔排序结果是:', shell_order_list)      
    
    # 归并排序
    merge_sort_list = merge_sort(L)
    print('归并排序结果是:', merge_sort_list)   
    
    # 快速排序
    quick_sort_list = quick_sort(L)
    print('快速排序结果是:', quick_sort_list)     
    
    
L1 = list([9,1,5,8,3,7,4,6,2])
L2 = list([9,1,5,8,3,7,4,6,2,11])

if __name__ == "__main__":
    print('---'*10 + 'L1' + '---'*10)
    print('L1原始数据是:', L1)
    main(L1)
    print('---'*10 + 'L2' + '---'*10)
    print('L2原始数据是:', L2)
    main(L2)
    

排序结果:

------------------------------L1------------------------------
L1原始数据是: [9, 1, 5, 8, 3, 7, 4, 6, 2]
堆排序结果是: [1, 2, 3, 4, 5, 6, 7, 8, 9]
简单交换排序结果: [1, 2, 3, 4, 5, 6, 7, 8, 9]
冒泡排序结果是: [1, 2, 3, 4, 5, 6, 7, 8, 9]
简单选择排序结果是: [1, 2, 3, 4, 5, 6, 7, 8, 9]
直接插入排序结果是: [1, 2, 3, 4, 5, 6, 7, 8, 9]
希尔排序结果是: [1, 2, 3, 4, 5, 6, 7, 8, 9]
归并排序结果是: [1, 2, 3, 4, 5, 6, 7, 8, 9]
快速排序结果是: [1, 2, 3, 4, 5, 6, 7, 8, 9]
------------------------------L2------------------------------
L2原始数据是: [9, 1, 5, 8, 3, 7, 4, 6, 2, 11]
堆排序结果是: [1, 2, 3, 4, 5, 6, 7, 8, 9, 11]
简单交换排序结果: [1, 2, 3, 4, 5, 6, 7, 8, 9, 11]
冒泡排序结果是: [1, 2, 3, 4, 5, 6, 7, 8, 9, 11]
简单选择排序结果是: [1, 2, 3, 4, 5, 6, 7, 8, 9, 11]
直接插入排序结果是: [1, 2, 3, 4, 5, 6, 7, 8, 9, 11]
希尔排序结果是: [1, 2, 3, 4, 5, 6, 7, 8, 9, 11]
归并排序结果是: [1, 2, 3, 4, 5, 6, 7, 8, 9, 11]
快速排序结果是: [1, 2, 3, 4, 5, 6, 7, 8, 9, 11]

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

西瓜情怀总是籽

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值