python实现基本排序算法

排序(python)

冒泡排序

从序列一端开始往另一端冒泡,一次比较两个相邻的数的大小,两层循环,外层冒泡轮数,里层一次比较,时间复杂度 o ( n 2 ) o(n^2) o(n2)


code


def Bubble_Sort(arr: list[int]):
    for i in range(len(arr)):
        isSort = True  # 冒泡排序不关心原数据是否已经有序
        for j in range(len(arr)-i-1):
            if arr[j] < arr[j+1]:
                arr[j], arr[j+1] = arr[j+1], arr[j]
                isSort = False
        if isSort:  # 原数据已经有序,直接结束
            break

选择排序

先找到列表中最小的元素,将它和列表的第一个元素交换位置,第二步,在剩下的元素中继续寻找最小的元素,依次下去 o ( n 2 ) o(n^2) o(n2)


code

def Select_sort(arr: list):
    for i in range(len(arr)):
        min = i  # 最小元素的坐标
        for j in range(i+1, len(arr)):
            if arr[j] < arr[min]:
                min = j
        arr[min], arr[i] = arr[i], arr[min]  # 和待排序数组的第一个元素交换

插入排序

把待排序列表分成,“已排序”和“未排序”两部分,初始状态就是已排序为空,为排序为整个列表,然后从未排序部分抽出一个数,有序的插入已排序部分(找到待插入的位置),直到全部排序,时间复杂度 O ( n 2 ) O(n^2) O(n2)


code

def Insert_sort(arr: list):
    n = len(arr)
    for i in range(1, n):
        value = arr[i]
        j = i-1  # 待插入的位置
        while j >= 0:
            if arr[j] > value:
                a[j+1] = arr[j]  # 移动数组,也就是在寻找插入位置
            else:
                break
            j -= 1
        arr[j+1] = value

希尔排序

又名 “缩小增量排序”,是插入排序的一种改进版本,因为插入排序对大规模的乱序数组的效率比较慢,因为每次只移动一个位置,希尔排序加快了插入的速度。让数据可以跳跃移动


code

def Shell_sort(arr: list):
    length = len(arr)
    gap = 1  # 区间,可以自己决定
    while gap < length:
        gap = gap * 3 + 1
    while gap > 0:  # 插入排序是一种特殊的希尔排序
        for i in range(gap, length):
            tmp = arr[i]
            j = i - gap
            while j >= 0 and arr[j] > tmp:
                arr[j+gap] = arr[j]
                j -= gap
            arr[j + gap] = tmp
        gap = gap // 3

归并排序

核心思想:分治法,将一个数组分成两部分,递归分,知道分成单个元素,然后重新组装和合并。给你两个有序数组,将他们合并成一个新的有序数组,只有一个元素的数组肯定有序。


code

def merge_sort(arr: list):

    def merge(arr, tempArr, start, mid, end):
        tempArr[start:end+1] = arr[start:end+1]
        left, right = start, mid+1
        for k in range(start, end+1):
            if left > mid:
                arr[k] = tempArr[right]
                right += 1
            elif right > end:
                arr[k] = tempArr[left]
                left += 1
            elif tempArr[right] < tempArr[left]:
                arr[k] = tempArr[right]
                right += 1
            else:
                arr[k] = tempArr[left]
                left += 1

    def sort(arr, tempArr, start, end):
        if start >= end:
            return
        mid = start + (end - start) // 2
        sort(arr, tempArr, start, mid)
        sort(arr, tempArr, mid+1, end)
        merge(arr, tempArr, start, mid, end)
    # start sort()
    tempArr = [0] * len(arr)
    sort(arr, tempArr, 0, len(arr)-1)

快速排序

核心思想:依然是分治法,每次从序列中选出一个基准值,一次和其它基准值做比较,大于基准值放右边,小的放左边


code
递归

def quicksort(array: list[int]):
    if len(array) < 2:
        return array  # 结束
    else:
        pivot = array[0]
        less = [i for i i array[1:] if i <= pivot]
        greater = [i for i in array[1:] if i > pivot]
        return quickosrt(less) + [pivot] + quicksort(greater)

code
单边扫描

def quick_sort(array):

    def partition(array, startIndex, endIndex):
        # 对这部分修改可以写双边扫描
        pivot = array[startIndex]  # 取基准值
        mark = startIndex  # 初始化下标
        for i in range(startIndex+1, endIndex+1):
            if array[i] < pivot:
                mark += 1
                array[i], array[mark] = array[mark], array[i]
        # 基准值与mark对应的元素调换位置
        array[startIndex] = array[mark]
        array[mark] = pivot

    def sort():
        if endIndex <= startIndex:
            return
        pivotIndex = partition(array, startIndex, endIndex)
        sort(array, startIndex, pviotIndex-1)
        sort(array, pviotIndex+1, endIndex)

    # 虽然依然使用了递归,但是都是在原数组上的操作
    sort(array, 0, len(array)-1)

code
非递归+双边扫描

def quick_sort(array: list):

    def partition(array, left, right):
        if not array or right<=0 or left >= right:
            return
        
        mid = (left + right) //  2;
        
        pivot = array[mid]
        i, j = left-1, right+1
        while i < j:
            
            i += 1
            while array[i] < pivot: 
                i += 1
                   
            j -= 1 
            while array[j] > pivot:
                j -= 1
            if i < j:  
                array[i], array[j] = array[j], array[i]
        return j

    def Q_sort(array, left, right):
        if not array or right <= 0 or left >= right:
            return

        temp = [] # stack
        i, j = 0, 0
        temp.append(right)
        temp.append(left)
        # print(temp)

        while temp:
            # print(array)
            i = temp.pop()
            j = temp.pop()
            if i < j:
                # print(i, j)
                k = partition(array, i, j)
                # print("k:", k)
                if k > i:
                    temp.append(k)
                    temp.append(i)
                if j > k:
                    temp.append(j)
                    temp.append(k+1)

    Q_sort(array, 0, len(array)-1)

if __name__ == "__main__":
    B = int(input().strip())
    A = list(map(int, input().strip().split()))
    
    # print(A)

    quick_sort(A)
    for a in A:
        print(a, end=' ')

堆排序

把堆看作一颗完全二叉树,首先将待排序数组构造成完全二叉树。
接着就要将这颗没有规律的完全二叉树变成大根堆、小根堆,堆顶元素就是整棵树的最大值(最小值),对于子树也是如此。每次从堆顶取出元素后,重建整个堆(其实微调就可以了)


code

def Heap_sort(self, arr: list):

    def sink(arr: list, index: int, length: int):
        # 原始数据的顺序,作为初始化树的层次遍历顺序,然后再把这棵树变成大根堆。
        leftChild = 2*index + 1
        rightChild = 2*index + 2
        present = index

        if leftChild < length and arr[leftChild] > arr[present]:
            present = leftChild

        if rightChild < length and arr[rightChild] > arr[present]:
            present = rightChild

        if present != index:  # 下标不等,意味着需要调换元素值
            arr[index], arr[present] = arr[present], arr[index]
            sink(arr, present, length)

    def buildHeap(arr: list, length: int):
        # 此处构建完全二叉树,下标是以0 开始的
        for i in range(length//2-1, -1, -1):  # 从最后一个叶子结点的父节点开始调整整棵树
            sink(arr, i, length)

    length = len(arr)
    buildHeap(arr, length)
    print('init_heap', arr)
    for i in range(length-1, 0, -1):
        arr[0],arr[i] = arr[i], arr[0]
        length -= 1
        sink(arr, 0, length)

计数排序

def Count_sort(self, arr: list):
        maxn = max(arr)

        countArr = [0] * (maxn+1)

        for index, num in enumerate(arr):
            countArr[num] += 1
            arr[index] = 0

        index = 0
        for i in range(len(countArr)):
            for _ in range(countArr[i]):
                arr[index] = i
                index += 1

欢迎一起来参与leetcode刷题项目

刷题的GitHub: github链接.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值