python 学习之常见排序算法

本文用python实现插入排序,交换排序,选择排序,归并排序,基数排序。其中插入排序分直接插入排序与希尔排序, 交换排序分冒泡排序与快速排序, 选择排序分简单选择排序与堆排序。

1, 直接插入排序

  • 时间复杂度:O(n²)
  • 空间复杂度:O(1)
  • 稳定性:稳定
def insert_sort(lists):
    count = len(lists)
    for i in range(1, count):
        key = lists[i]
        j = i - 1
        while j >= 0 :
            if key >= lists[j]:
                break
            lists[j+1] = lists[j]
            lists[j] = key
            j = j-1
    return lists

if __name__ == '__main__':
    lst = [2, 4, 3, 1, 1]
    print(insert_sort(lst))

2, 希尔排序(缩小增量排序)

  • 时间复杂度:O(n)
  • 空间复杂度:O(n√n)
  • 稳定性:不稳定
#!/usr/bin/env python3
#-*- coding:utf8 -*-
def shell_sort(lists):
    count = len(lists)
    step = count//2
    while step > 0:
        for i in range(step, count):
            key = lists[i]
            j = i
            while j>= step and key < lists[j-step]:
                lists[j] = lists[j-step]
                j = j-step
            lists[j] = key
        step = step//2
    return lists

if __name__ == '__main__':
    lst = [2, 42, 3, 11, 1, 18, 22, 7]
    print(shell_sort(lst))

3, 简单选择排序

  • 时间复杂度:O(n²)
  • 空间复杂度:O(1)
  • 稳定性:不稳定
#!/usr/bin/env python3
#-*- coding:utf8 -*-
def select_sort(lists):
    count = len(lists)
    for j in range(count-1):
        min = j   #min index
        for i in range(j+1, count):
            if lists[i] < lists[min]:
                min = i
        lists[min], lists[j] = lists[j], lists[min]
    return lists

if __name__ == '__main__':
    lst = [2, 42, 3, 11, 1, 18, 22, 7]
    print(select_sort(lst))

4, 堆排序

  • 时间复杂度:O(nlog₂n)
  • 空间复杂度:O(1)
  • 稳定性:不稳定
#!/usr/bin/env python3
#-*- coding:utf8 -*-
import random

def max_heapify(heap, heap_size, root):
    '''在堆中做结构调整,使得父节点大于子节点'''
    left = 2*root + 1
    right = left + 1
    larger = root
    if left < heap_size and heap[left] > heap[larger]:
        larger = left
    if right < heap_size and heap[right] > heap[larger]:
        larger = right
    if larger != root:
        heap[larger], heap[root] = heap[root], heap[larger]
        max_heapify(heap, heap_size, larger)

def build_max_heap(heap):
    '''构造一个堆,将堆中数据重新排序'''
    heap_size = len(heap)
    for i in range((heap_size-1)//2, -1, -1):
        max_heapify(heap, heap_size, i)

def heap_sort(heap):
    # 根据列表建立最大根堆
    build_max_heap(heap)
    for i in range(len(heap)-1, -1, -1):
    # 将堆中根节点与i节点对调 再调整前面len-1个节点
        heap[0], heap[i] = heap[i], heap[0]
        max_heapify(heap, i, 0)

if __name__ == '__main__':
    a = [30, 50, 57, 77, 62, 78, 94, 80, 84]
    print(a)
    heap_sort(a)
    print(a)
    b = [random.randint(1,1000) for i in range(20)]
    print(b)
    heap_sort(b)
    print(b)

5, 冒泡排序

  • 时间复杂度:O(n²)
  • 空间复杂度:O(1)
  • 稳定性:稳定
#!/usr/bin/env python3
#-*- coding:utf8 -*-

def bubble_sort(lists):
    size = len(lists)
    i = 0
    while i < (size-1):
        for j in range(size-1, i, -1):
            if lists[j] < lists[j-1]:
                lists[j], lists[j-1] = lists[j-1], lists[j]
        i += 1
    return lists

if __name__ == '__main__':
    lst = [2, 42, 3, 11, 1, 18, 22, 7]
    print(bubble_sort(lst))

6, 快速排序

  • 时间复杂度:O(nlog₂n)
  • 空间复杂度:O(nlog₂n)
  • 稳定性:不稳定
#!/usr/bin/env python3
#-*- coding:utf8 -*-

def quick_sort(lists, start, end):
    if start < end:
        # 基准数设置
        base = lists[start]
        # i 从前向后搜索 j 从后向前搜索
        i = start
        j = end
        while i < j:
            while (i<j) and (lists[j] >= base):
                j -= 1
            lists[i] = lists[j]
            while (i < j) and lists[i] <= base:
                i += 1
            lists[j] = lists[i]
        lists[i] = base

        # 递归前后半区
        quick_sort(lists, start, i-1)
        quick_sort(lists, j+1, end)
    return  lists

if __name__ == '__main__':
    lst = [2, 42, 3, 11, 1, 18, 22, 7]
    print(quick_sort(lst, 0, len(lst)-1))

7, 归并排序

  • 时间复杂度:O(nlog₂n)
  • 空间复杂度:O(1)
  • 稳定性:稳定
#!/usr/bin/env python3
#-*- coding:utf8 -*-

def merge(a, b):
    c = []
    i = j = 0

    while i < len(a) and j < len(b):
        if a[i] < b[j]:
            c.append(a[i])
            i += 1
        else:
            c.append(b[j])
            j += 1

    if i == len(a):
        c += b[j:]
    else:
        c += a[i:] 
    return c

def merge_sort(lists):
    if (len(lists)<=1):
        return lists

    middle = len(lists)//2
    left = merge_sort(lists[:middle])
    right = merge_sort(lists[middle:])
    return merge(left, right)

if __name__ == '__main__':
    lst = [2, 42, 3, 11, 1, 18, 22, 7]
    print(merge_sort(lst))

8, 基数排序

  • 时间复杂度:O(d(r+n))
  • 空间复杂度:O(rd+n)
  • 稳定性:稳定
#! /usr/bin/env python3
#-*-coding=utf-8-*-

#基于桶排序的基数排序
from random import randint

def RadixSort(list,d):    
    for k in range(d):#d轮排序
        s=[[] for i in range(10)]#因为每一位数字都是0~9,故建立10个桶
        '''对于数组中的元素,首先按照最低有效数字进行
           排序,然后由低位向高位进行。'''
        for i in list:
            '''对于3个元素的数组[977, 87, 960],第一轮排序首先按照个位数字相同的
               放在一个桶s[7]=[977],s[7]=[977,87],s[0]=[960]
               执行后list=[960,977,87].第二轮按照十位数,s[6]=[960],s[7]=[977]
               s[8]=[87],执行后list=[960,977,87].第三轮按照百位,s[9]=[960]
               s[9]=[960,977],s[0]=87,执行后list=[87,960,977],结束。'''
            s[i//(10**k)%10].append(i)  # 977/10=97(小数舍去),87/100=0
        list=[j for i in s for j in i]
    return list

if __name__ == '__main__':
    a=[54, 21, 42, 12, 30, 88, 50, 24, 63] # 最多是二位数,d取2
    print(a)
    a=RadixSort(a,2)  # 将排好序的数组再赋给a!!!!
    print(a)

感谢文档:
堆排序的python实现
归并排序详解(python实现)
快速排序
利用Python实现堆排序
八大排序算法的 Python 实现

猜你喜欢

转载自blog.csdn.net/jiulixiang_88/article/details/80928774