数据结构与算法中的排序算法(一)


列表排序

  • 排序:将一组“无序”的记录序列调整为“有序”的记录序列

  • 列表排序:将无序列表变为有序列表

    • 输入:列表
    • 输出:有序列表
  • 升序与降序

  • 内置排序函数:sort()

冒泡排序(Bubble Sort)

  • 列表每两个相邻的数,如果前面比后面大,则交换这两个数

  • 一趟排序完成后,则无序区减少一个数,有序区增加一个数

  • 代码关键点:趟、无序区范围

代码示例

import random

def bubble_sort(li):
    for i in range(len(li)-1):  # 第i趟
        for j in range(len(li)-i):
            if li[j]>li[j+1]:
                li[j],li[j+1]=li[j+1],li[j]

#验证
li = [random.randint(0,10000) for i in range(1000)]
print(li)
bubble_sort(li)
print(li)
  • 时间复杂度:O(n2)

冒泡排序-优化

  • 如果冒泡排序中的一趟排序没有发生交换,则说明列表已经有序,可以直接结束算法。

代码示例

def bubble_sort(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:
                return
  • 时间复杂度:O(n2)

选择排序(Select Sort)

  • 一趟排序记录最小的数,放到第一个位置

  • 再一趟排序记录列表无序最小的数,放到第二个位置

  • 算法关键点:有序和无序区、无序区最小数的位置

代码示例:

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
        if min_loc != i:
            li[i], li[min_loc] = li[min_loc], li[i]

插入排序(Inset Sort)

  • 初始时手里(有序区)只有一张牌

  • 每次(从无序区)摸一张牌,插入到手里已有牌的正确位置

代码示例:

def insect_sort(li):
    for i in range(1,len(li)):
        tmp = li[i]
        j = i - 1
        while j >= 0 and tmp < li[j]:
            li[j+1] = li[j]
            j = j - 1
         li[j+1] = tmp
  • 时间复杂度:O(n2)

快速排序(Quick Sort)

  • 快速排序:

  • 快速排序思路:

    • 取一个元素p(第一个元素),使元素p归位;
    • 列表被p分成两部分,左边都比p小,右边都比p大;
    • 递归完成排序

快速排序-框架:

def quick_sort(data,left,right):
    if left < right:
        mid = partition(data,left,right)
        quick_sort(data,left,mid-1)
        quick_sort(data,mid+1,right)

代码示例:

def partition(li,left,right):
    tmp = li[left]
    while left < right:
        while li[right] >= tmp:  # 从右边找比tmp小的数
            right -= 1  # 往左走一步
        li[left] = li[right]  # 把右边的值写到左边空位上
        while left < right and li[left] <= tmp:
            left += 1
        li[left] = tmp  # 把tmp归位
        return left
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)
#调用测试
li = [5,7,6,3,1,2,9,8]
quick_sort(li,0,len(li)-1)
print(li)  
  • 快速排序的效率:

    • 快速排序的时间复杂度:O(nlogn)
  • 快速排序的问题

    • 最坏情况:

      正序或逆序排列,二叉树画出来应该是一棵斜树,并且需要经过n-1次递归调用才能完成,且第i次划分需要经过n‐i次关键字的比较才能找到第i个记录,也就是枢轴的位置,所以:

      最终的时间复杂度应该O(n2)

    • 递归:消耗一部分系统资源


文章作者: 阿浩
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 阿浩 !
评论
  目录