Python数据结构与算法5-排序算法2

本文深入讲解希尔排序、快速排序及归并排序等经典排序算法,包括其实现方式、时间复杂度及稳定性分析,并对比二分查找算法,为读者提供全面的排序算法知识。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  • 希尔排序(Shell Sort)
    也称缩小增量排序,是基于插入排序的改进。属于非稳定排序算法,把元素按一定的下标增量分组,每组分别进行插入排序;逐渐减少增量值直至1,算法终止。

    实现方式:

# 4. 希尔排序
def shell_sort(alist):
    n = len(alist)
    gap = n//2
    while gap >= 1:
        for i in range(gap,n): # 从第gap+1个元素开始执行步长为gap的插入排序
            j = i
            while j > 0: # 步长为gap的插入排序
                if alist[j] < alist[j-gap]:
                    alist[j], alist[j-gap] = alist[j-gap], alist[j]
                else:
                    break
        gap = gap//2

最优时间复杂度:根据步长序列不同而不同
最差时间复杂度:O(n2):当步长直接取为1时,直接退化为插入排序
稳定性:不稳定:不同组内元素交换导致原有顺序破坏

  • 快速排序(Quicksort)
    也称划分交换排序(partition-exchange sort),从数列中选取一个基准值(pivot),重新排列数列,将所有比基准值小的元素放在其前面,大的放在其后面,完成分区(partition);将两个分区分别进行递归的(recursive)相应排序。

实现方式:

# 5. 快速排序
def quick_sort(alist, first, last): # 设置first、last参数方便在一个数列中完成递归
    if first >= last: # 当最终输入为单个元素或空值时,结束递归
        return
    n = len(alist)
    low = first
    high = last
    mid_value = alist[low]
    while low < high: # low与high相等时停止循环
        while low < high and alist[high] >= mid_value: # 首先移动high,将“=”条件置于high这边,相当于把与mid_value相等值均放在左边
            high -= 1
        alist[low] = alist[high] # 将high找到的小于mid_value的值放到low处
        
        while low < high and alist[low] < mid_value: # 移动low
            low += 1
        alist[high] = alist[low] # 将low找到的大于mid——value的值放到high处
    alist[low] = mid_value #此时low=high,已找到mid_value正确位置,将mid_value值放在该位置
    
    # 递归操作
    quick_sort(alist, first, low-1)
    quick_sort(alist, low+1, last)
    

最优时间复杂度:O(nlogn):每次选取的基准值恰好为当前序列的中位数(每次重新排列时间复杂度n,每次二分情况下重新排列总次数logn
最差时间复杂度:O(n2):每次选取的基准值恰好为当前序列中的最小或最大元素(每次重新排列时间复杂度n,重新排列总次数n)
稳定性:不稳定:不同组内元素交换导致原有顺序破坏

  • 归并排序
    采用分治法,先递归将数列二分分解数列至单个元素,再按分解结构逆向逐步两两合并为有序数列,合并采用指针遍历形式,直至最终重新合并为完整的有序数列。

    实现方式:

# 6. 归并排序
def merge_sort(alist):
    n = len(alist)
    if n <= 1: # 当已分解为单一元素时,直接返回该元素
        return alist
    mid = n//2
    
    #递归,返回已排序好的左端和右端数列
    left_li = merge_sort(alist[:mid]) 
    right_li = merge_sort(alist[mid:])
    
    left_pointer, right_pointer = 0,0 # 创建排序指针
    result = []
    while left_pointer < len(left_li) and right_pointer < len(right_li): #移动左右指针,选取两者较小元素依次插入result
        if left_li[left_pointer] <= right_li[right_pointer]: #使用“<=”时,归并排序为稳定排序
            result.append(left_li[left_pointer])
            left_pointer += 1
        else:
            result.append(right_li[right_pointer])
            right_pointer += 1
            
    #退出循环时,左右端数列必有至少一个为空,另一个可能有剩余
    result += left_li[left_pointer:] # 将剩余的有序数列直接插入result尾部
    result += right_li[right_pointer:]
    return result      

最优时间复杂度:O(nlogn):每级排序时间复杂度为n,总共需要logn步合并
最差时间复杂度:O(nlogn):与最优时间复杂度一样
稳定性:稳定:当左右子集出现相同元素时,优先选择左集元素,可使归并排序稳定

  • 常见排序算法比较
    在这里插入图片描述

  • 二分法查找(Binary Search)
    又称折半查找,每次比较有序表的中间位置值与查找关键字,如不必配则取原表的一半继续执行,直至子表不存在位置。
    优点:比较次数少,查找速度快,平均性能好
    缺点:只能作用于有序顺序表,因为需要起始和终止下标来寻找中间位置,且插入删除困难。
    比较适用于不常变动但查找频繁的有序列表。

    递归方式实现:

    # 二分查找法(递归)
    def binary_search(alist, item):
        n = len(alist)
        if n == 0: # 递归退出条件
            return False
        mid = n//2
        if alist[mid] == item:
            return True
        elif alist[mid] > item:
            return binary_search(alist[:mid], item)
        else:
            return binary_search(alist[mid+1:], item)
    

    非递归方式实现:

    # 二分查找法(非递归)
    	def binary_search(alist, item):
    	    n = len(alist)
    	    first = 0 # 通过更改下标方式完成二分查找
    	    last = n-1
    	    while first <= last: # 循环终止条件
    	        mid = (first+last)//2
    	        if alist[mid] == item:
    	            return True
    	        elif alist[mid] > item:
    	            last = mid-1
    	        else:
    	            first = mid+1
    	    return False
    

    最优时间复杂度:O(1)
    最差时间复杂度:O(logn)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值