算法工程师之排序算法-Python

一个合格的算法工程师应该具有熟练写各种排序算法的本领

1,快速排序(n*logn)

分治法,主要是它的划分过程,即选取一个值将list中不大于该数的放在该数左边,不小于该数的放在该数右边,然后分别对左右两个区间递归划分。

def sortmy(arr, low, high):
    if low < high:
        n = partition(arr, low, high)
        sortmy(arr, low, n - 1)
        sortmy(arr, n+1, high)


def partition(arr, low, high):
    key = arr[low]
    while low < high:
        while low < high and arr[high] >= key:
            high -= 1
        arr[low] = arr[high]
        while low < high and arr[low] <= key:
            low += 1
        arr[high] = arr[low]

    arr[low] = key
    return low


arr = list(map(int, input().split()))
sortmy(arr, 0, len(arr) - 1)
print(arr)

2, 冒泡排序(n^2)

每次循环将最大的值放在数组最后

def sortmy(arr, n):
    while n:
        for i in range(n-1):
            if arr[i] > arr[i+1]:
                arr[i], arr[i+1] = arr[i+1], arr[i]
        n -= 1


arr = list(map(int, input().split()))
sortmy(arr, len(arr))
print(arr)

3,堆排序(n*logn)

先构建大根堆(没有排好序),然后将堆顶位置的值(即最大值)与最后一个值交换,然后再将更新后的大根堆进行重新构建,最后会得到一个排好序的数组。具体参考堆的构建及堆排序(C++)

def sortmy(arr, n):
    for i in range(int(n / 2 - 1), -1, -1):
        heapAdjust(arr, i, n - 1)

    while n - 1:
        arr[0], arr[n - 1] = arr[n - 1], arr[0]
        n -= 1
        heapAdjust(arr, 0, n - 1)


def heapAdjust(arr, low, high):
    """
    构建大根堆
    :param arr:
    :param low:
    :param high:
    :return:
    """
    rc = arr[low] # 头节点
    i = low * 2 + 1 # 左孩子
    while i <= high:
        if i < high: # 不是最后一个节点
            if arr[i] < arr[i + 1]: # 左孩子比右孩子小
                i += 1

        if rc > arr[i]: # 头节点大于孩子节点就不操作
            break

        arr[low] = arr[i] # 否则将较大的孩子节点赋值给头节点
        low = i # 开始将这个较大节点作为新头节点继续遍历
        i = 2 * i + 1

    arr[low] = rc # 循环执行完毕需要将一开始的头节点赋值给循环中的新头节点


arr = list(map(int, input().split()))
sortmy(arr, len(arr))
print(arr)

4、归并排序

分而治之,核心是将两个有序数组组合成一个有序数组,即下面的归并过程代码

import copy
import random


def merge(arr, start, mid, end):
    """
    归并过程
    :param arr:
    :param start:
    :param end:
    :return:
    """
    res = copy.deepcopy(arr)
    Mid = mid
    for idx in range(start, end + 1):
        if start > Mid: # 左分支已遍历完
            arr[idx] = res[mid + 1]
            mid += 1
        elif mid == end: # 右分支已遍历完
            arr[idx] = res[start]
            start += 1
        elif res[start] <= res[mid + 1]: # 左分支的值小于右分支
            arr[idx] = res[start]
            start += 1
        else:
            arr[idx] = res[mid + 1] # 左分支的值大于右分支
            mid += 1


def merge_sort(arr, start, end):
    """
    归并排序递归函数
    :param arr: 
    :param start: 
    :param end: 
    :return: 
    """
    if end == start:
        return
    mid = int((start + end) / 2)
    merge_sort(arr, start, mid)
    merge_sort(arr, mid + 1, end)
    merge(arr, start, mid, end)


a = random.sample(range(100), 100)
print(a)
merge_sort(a, 0, len(a) - 1)
print(a)

5、选择排序

挺垃圾的一种排序方法,还不如冒泡

import random


def select_sort(arr, n):
    """
    选择排序
    :param arr:
    :return:
    """
    for i in range(n):
        minIdx = i
        for j in range(i, n):
            if arr[j] < arr[minIdx]:
                minIdx = j

        if minIdx != i:
            arr[i], arr[minIdx] = arr[minIdx], arr[i]


a = random.sample(range(100), 100)
print(a)
select_sort(a, len(a))
print(a)

6、插入排序

时间复杂度也挺高,但是代码实现起来设计巧妙如下,循环遍历数组,将未排序的数一个个插入到前面已排好序的数组中,未申请额外空间

import random


def insert_sort(arr, n):
    """
    插入排序
    :param arr:
    :param n:
    :return:
    """
    for i in range(1, n):
        for j in range(i - 1, -1, -1):
            if arr[j+1] < arr[j]:
                arr[j], arr[j + 1] = arr[j + 1], arr[j]


a = random.sample(range(100), 100)
print(a)
insert_sort(a, len(a))
print(a)

7、希尔排序

插入排序的改进版,设计的非常巧妙,也可以说插入排序是特殊情况的希尔排序,即gap设为1时,两者就是一样的。只不过shell由小及大,通过设置不同的增量(这里的增量是[n/2, n/2/2, ..., 1],也可以设为其他)来实现最终的排序。

import random


def shell_sort(arr, n):
    """
    希尔排序
    :param arr:
    :param n:
    :return:
    """
    gap = int(n / 2)
    while gap:
        for i in range(gap, n):
            for j in range(i - gap, -1, -gap):
                if arr[j] > arr[j + gap]:
                    arr[j], arr[j + gap] = arr[j + gap], arr[j]

        gap = int(gap / 2)


a = random.sample(range(100), 100)
print(a)
shell_sort(a, len(a))
print(a)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值