排序算法 冒泡排序 快排 归并排序

本文深入解析了三种主要的排序算法:冒泡排序、快速排序和归并排序。详细介绍了每种算法的实现步骤、时间复杂度及稳定性。通过具体实例,展示了算法的工作原理,帮助读者理解并掌握这些基本排序算法。

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

在这里插入图片描述

冒泡排序

冒泡排序(Bubble Sort)也是一种简单直观的排序算法。它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。
步骤:

  1. 比较相邻的元素。如果第一个比第二个大,就交换他们两个。
  2. 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数。
  3. 针对所有的元素重复以上的步骤,除了最后一个。
  4. 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
    时间复杂度:平均:O(n^2) ,最好情况:当输入数据正序时,为O(n); 最坏情况:当输入的数据是反序时,为 O(n^2)
    稳定性:因为array[j]==array[j+1]的时候,我们可以不移动array[i]和array[j],所以冒泡排序是稳定的。
def bubbleSort(arr):
    for i in range(1, len(arr)):
        for j in range(0, len(arr)-i):
            if arr[j] > arr[j+1]:
                arr[j], arr[j + 1] = arr[j + 1], arr[j]
    return arr

快速排序

时间复杂度:平均为O(nlogn),最坏情况O(n^2),每次所选的中间数是当前序列中的最大或最小元素;
最好情况:每次划分所选择的中间数恰好将当前序列几乎等分,整个算法的时间复杂度为O(nlogn)。
最坏情况:每次划分所选的数都很偏,为数组的最大值或最小值,此时相当于冒泡排序(每次排好一个元素的位置),时间复杂度为O(n^2)。解决办法:选pivot的时候可以随机选,而不是每次选第一个或者最后一个。
挖坑填数的思想
快排就是一个选定基准点后不断和基准点比较的过程,比基准大的放到右边,比基准小的或相等的放到左边。
1、i =left; j = right;首先选定数组第一个数为基准数nums[i],并把它赋值给temp, 相当于挖了一个坑,把坑中原来的数用temp保存起来。
2、要先从后往前找。先从后往前找一个比他小的数nums[j],找到这个数之后将其挖出此数填到之前的坑中nums[i]=nums[j],这时nums[j]又有了一个坑。再从前往后找比基准数大的,填到刚才挖的坑中,两种行为交替进行,直到i>=j;这个时候基准temp就找到了它正确的位置 i,所以num[i]=temp;
3、然后进行递归,递归进行时要求left<right,即递归的出口时left>=right

def quick_sort(num, left, right):
    if left<right:
        temp = num[left]
        print(num)
        print('left ', left)
        print('right ', right)
        i = left 
        j = right 
        while i<j:
            while i<j and num[j]>temp:
                j -= 1
            num[i] = num[j]
            while i<j and num[i]<=temp:
                i += 1
            num[j] = num[i]
        # 基准找到了它正确的位置
        num[i] = temp
        # 再对基准的左边进行排序
        quick_sort(num, left, i-1)
        # 对基准的右边进行排序
        quick_sort(num, i+1, right)

if __name__ == "__main__":
    num = [4,1,2,7,3,5,4,8,6,44,0,23]
    quick_sort(num, 0, len(num)-1)
    print(num)

归并排序

时间复杂度为O(nlogn),最好最坏情况都一样。空间复杂度为O(n)。
思路:归并排序的根本思路就是将两个有序数组合并为一个有序数组。问题的关键就是如何将无序数组分为有序数组。可以采用递归的方式,当一直递归到每个数组中只有一个数时,这个数组就相当于排好序了。

def mergeSort(arr):
    if(len(arr)<2):
        return arr
    # 二分
    middle = len(arr) // 2 
    left, right = arr[0:middle], arr[middle:]
    # 递归 
    return merge(mergeSort(left), mergeSort(right))

# 合并两个排好序的数组
# left,right两个数组均已经排好序
def merge(left,right):
    result = []
    while left and right:
        if left[0] <= right[0]:
            result.append(left.pop(0))
        else:
            result.append(right.pop(0))
    while left:
        result.append(left.pop(0))
    while right:
        result.append(right.pop(0))
    return result
arr = [3,2,5,8,9,6,4,1]
temp = mergeSort(arr)
print(temp)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值