Python数据结构与算法:排序

参考:
基本排序算法
面试必备 | 排序算法的Python实现


基本排序算法

冒泡排序

def bubble_sort(seq):
    n = len(seq)
    for i in range(n-1):
        for j in range(n-1-i):
            if seq[j] > seq[j+1]:
                seq[j], seq[j+1] = seq[j+1], seq[j]

每次都从第一个元素开始,每次排好当前最大的元素。

选择排序

def select_sort(seq):
    n = len(seq)
    for i in range(n-1):
        min_idx = i 
        for j in range(i+1, n):
            if seq[j] < seq[min_idx]:
                min_idx = j
        if min_idx != i:
            seq[i], seq[min_idx] = seq[min_idx], seq[i]

每次选择出最小的元素。

插入排序

def insertion_sort(seq):
    n = len(seq)
    for i in range(1, n):
        value = seq[i]
        pos = i
        while pos > 0 and value < seq[pos-1]:
            seq[pos] = seq[pos-1]
            pos-=1
        seq[pos] = value

注意:范围是到n。

高级排序算法

分治法:递归。分解,解决,合并。

归并排序
归并排序把数组递归成只有单个元素的数组,之后再不断两两 合并,最后得到一个有序数组。这里的递归基本条件就是只包含一个元素的数组,当数组只包含一个元素的时候,我们可以认为它本来就是有序的(当然空数组也不用排序)。

def merge_sort(seq):
    if len(seq) <= 1:    #只有一个元素时是递归出口
        return seq
    else:
        mid = int(len(seq)/2)
        left_half = merge_sort(seq[:mid])
        right_half = merge_sort(seq[mid:])

        # 合并两个有序的数组
        new_seq = merge_sorted_list(left_half, right_half)
        return new_seq

def merge_sorted_list(sorted_a, sorted_b):
    length_a, length_b = len(sorted_a), len(sorted_b)
    a = b = 0
    new_sorted_list = list()

    while a < length_a and b < length_b:
        if sorted_a[a] < sorted_b[b]
            new_sorted_list.append(sorted_a[a])
            a += 1
        else:
            new_sorted_list.append(sorted_b[b])
            b += 1

    # 将剩下多余的放入有序数组
    while a < length_a:
        new_sorted_list.append(sorted_a[a])
        a += 1
    while b < length_b:
        new_sorted_list.append(sorted_b[b])
        b += 1

    return new_sorted_list 

快速排序
1.从序列当中选择一个基准数(pivot),简单起见可以选择第一个;
2.将序列当中的所有数依次遍历,比基准数大的位于其右侧,比基准数小的位于其左侧;
3.重复步骤1.2,直到所有子集当中只有一个元素为止;

设第0个位置为pivot,设置首尾俩个指针 left, right,两个指针不断向中间收拢。如果遇到 left 位置的元素大于 pivot 并且 right 指向的元素小于 pivot,我们就交换这俩元素,当 left > right 的时候退出就行了,这样实现了一次遍历就完成了 partition。


def quicksort_inplace(array, beg, end):    # 注意这里我们都用左闭右开区间,end 传入 len(array)
    if beg < end:    # beg == end 的时候递归出口
        pivot = partition(array, beg, end)
        quicksort_inplace(array, beg, pivot)
        quicksort_inplace(array, pivot+1, end)

def partition(array, beg, end):
    pivot_index = beg
    pivot = array[pivot_index]
    left = pivot_index + 1
    right = end - 1       #开区间,最后一个元素位置是end-1  [0, end-1] or [0: end),括号表示开区间

    while True:
        while left <= right and array[left] < pivot:
            left += 1
        while right >= left and array[right] >= pivot:
            right -= 1

        if left > right:
            break
        else:
            array[left], array[right] = array[right], array[left]

    array[pivot_index], array[right] = array[right], array[pivot_index]
    return right
def quicksort(lists,left,right):
    if left >= right:
        return lists
    key = lists[left]
    low = left
    high = right
    while left < right:
        while left < right and lists[right] >= key:
            right -= 1
        lists[left] = lists[right]
        while left < right and lists[left] <= key:
            left += 1
        lists[right] = lists[left]
    lists[right] = key
    quicksort(lists,low,left-1)
    quicksort(lists,left+1,high)
    return lists
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值