排序算法

2019-05-30  本文已影响0人  pubalabala

冒泡排序(优化)

def bubble_sort(origin_items, comp = lambda x, y: x > y):
    """冒泡排序 - 平方复杂度 - O(N**2)"""
    items = origin_items[:] # 此处优化算法不对原始数据造成影响
    for i in range(1, len(items),):
        swapped = False
        for j in range(0, len(items)-i):
            if comp(items[j], items[j+1]): # 此处解耦比较运算符, 扩大函数适用范围
                items[j], items[j+1] = items[j+1], items[j]
                swapped = True

       # 此处优化为双向排序, 经过此优化后的冒泡排序算法又称为搅拌排序、鸡尾酒排序等
       for j in range(len(items) - i, 0, -1):
             if comp(items[j-1], items[j]):
                 items[j], items[j-1] = items[j-1], items[j]
                 swapped = True
        if not swapped: # 如果某一轮比较全程没有发生交换则终止循环
            break
    return items

归并排序

归并排序的算法描述如下:

def merge(items1, items2, comp):
    """有序列表合并"""
    items = []
    index1, index2 = 0, 0
    while index1 < len(items1) and index2 < len(items2):
        if comp(items[index1], items2[index2]):
            items.append(items1[index1]
            index1 += 1
        else:
            items.append(items2[index2])
            index2 += 1
    items += items1[index1:]
    items += items2[index2:]
    return items


# 函数的递归调用 - 一个函数如果直接或者简介的调用了自身就成为递归调用
# 写递归调用的函数又两个关键点:
# 1. 收敛条件 - 什么时候可以停止递归
# 2. 递归公式 - 下一轮的调用跟当前轮次的关系
def merge_sort(items, comp=lambda x, y: x <= y):
    """归并排序"""
    if len(items) < 2:
        return items[:]
    mid = len(items) // 2
    left = merge_sort(items[:mid])
    right = merge_sort(items[mid:])
    return merge(left, right, comp)

插入排序

def insert_sort(items):
    for i in range(1, len(items)):
        for j in range(i):
            if items[j] > items[i]:
                items.insert(j, items.pop(i))
                break

# 或者
def insert_sort(items):
    for i in range(1, len(items)):
        temp = items[i]
        for j in range(i, 0, -1):
            if temp < items[j-1]:
                items[j] = items[j-1]
                items[j-1] = temp
            else:
                break

快速排序

import random


# 三数取中
def get_mid(arr, left, right):
    mid = left + ((left-right)>>1)
    if arr[left] < arr[right]:
        if arr[mid] > arr[right]:
            return right
        elif arr[mid] < arr[left]:
            return left
        else:
            return mid
    else:
        if arr[mid] > arr[left]:
            return left
        elif arr[mid] < arr[right]:
            return right
        else:
            return mid


# 挖坑法
def partition1(arr, left, right):
    mid = get_mid(arr, left, right)
    arr[mid], arr[right] = arr[right], arr[mid]
    key = arr[right]
    while left < right:
        while left < right and arr[left] <= key:
            left += 1
        arr[right] = arr[left]
        while left < right and arr[right] >= key:
            right -= 1
        arr[left] = arr[right]
    arr[right] = key
    return right


# 左右指针法
def partition2(arr, left, right):
    mid = get_mid(arr, left, right)
    arr[mid], arr[right] = arr[right], arr[mid]
    key = right
    while left < right:
        while left < right and arr[left] <= arr[key]:
            left += 1
        while left < right and arr[right] >= arr[key]:
            right -= 1
        arr[left],arr[right] = arr[right], arr[left]
    arr[left], arr[key] = arr[key], arr[left]
    return left


# 前后指针法
def partition3(arr, left, right):
    mid = get_mid(arr, left, right)
    arr[right], arr[mid] = arr[mid], arr[right]
    cur = left
    pre = cur - 1
    while cur < right:
        if arr[cur] < arr[right]:
            pre += 1
            if pre != cur:
                arr[pre], arr[cur] = arr[cur], arr[pre]
        cur += 1
    pre += 1
    arr[pre], arr[right] = arr[right], arr[pre]
    return pre


def quick_sort(arr, left, right):
    if left >= right:
        return
    mid = partition1(arr, left, right)
    quick_sort(arr, left, mid-1)
    quick_sort(arr, mid+1, right)


def random_arr(length, min, max):
    arr = []
    for i in range(length):
        arr.append(random.randint(min, max))
    return arr


def main():
    arr = random_arr(100, 0, 10000)
    print(arr)
    quick_sort(arr, 0, len(arr)-1)
    print(arr)


if __name__ == '__main__':
    main()
上一篇 下一篇

猜你喜欢

热点阅读