排序专栏(冒泡,插入,选择,快速,堆)

排序专栏

1.冒泡排序

冒泡排序(Bubble Sort)也是一种简单直观的排序算法。它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为越小的元素会经由交换慢慢"浮"到数列的顶端。
冒泡排序

class Solution:
    def bubbleSort(self, arr):
        if not arr:
            return arr
        arr_len = len(arr)
        for i in range(arr_len):
            for j in range(0, arr_len-i-1):
                if arr[j] >arr[j+1]:
                    arr[j+1],arr[j] = arr[j],arr[j+1]
        return arr

2.插入排序

插入排序(英语:Insertion Sort)是一种简单直观的排序算法。它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。插入排序在实现上,在从后向前扫描过程中,需要反复把已排序元素逐步向后挪位,为最新元素提供插入空间。

在这里插入图片描述

class Solution:
    def insertSort(self, arr):
        if not arr:
            return arr
        arr_len = len(arr)
        for i in range(arr_len):
            temp = arr[i]
            j = i
            while j >= 1 and arr[j - 1] > temp:
                arr[j] = arr[j - 1]
                j -= 1
            arr[j] = temp
        return arr
        

3.选择排序

选择排序(Selection Sort)是一种简单直观的排序算法。它的工作原理是:首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的头部。以此类推,直到所有元素均排序完成。
选择排序

class Solution:

    def selectSort(self, arr):
        if not arr:
            return arr
        arr_len = len(arr)
        for i in range(arr_len):
            min_index = i
            for j in range(i+1, arr_len):
                if arr[j] < arr[min_index]:
                    min_index = j
            arr[i], arr[min_index] = arr[min_index], arr[i]
        return arr
        

4.快速排序

快速排序是一种非常高效的排序算法,采用 “分而治之” 的思想,把大的拆分为小的,小的拆分为更小的。其原理是,对于给定的记录,选择一个基准数,通过一趟排序后,将原序列分为两部分,使得前面的比后面的小,然后再依次对前后进行拆分进行快速排序,递归该过程,直到序列中所有记录均有序。
在这里插入图片描述

class Solution:
    def quickSort(self, arr, low, high):
        if low >= high:
            return arr
        key = arr[low]
        left = low
        right = high
        while left < right:
            while left < right and arr[right] >= key:
                right -= 1
            arr[left] = arr[right]
            while left < right and arr[left] < key:
                left += 1
            arr[right] = arr[left]
        arr[left] = key
        self.quickSort(arr, low, left - 1)
        self.quickSort(arr, left + 1, high)


我写的比较简介,详细内容可参考知乎博客:快速排序

5.堆排序

堆排序(Heapsort)是指利用堆这种数据结构所设计的一种排序算法。堆积是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。堆排序可以说是一种利用堆的概念来排序的选择排序。
堆排序有以下几个核心的步骤:
1.建堆:将待排序的数组初始化为大顶堆(或者小顶堆)
2.将堆顶元素与最后一个元素进行交换,除去最后一个元素外可以组建为一个新的大顶堆。
3.由于第二部堆顶元素跟最后一个元素交换后,新建立的堆不是大顶堆,需要重新建立大顶堆。重复上面的处理流程,直到堆中仅剩下一个元素。
在这里插入图片描述

class Solution:
    def heapSort(self, arr):
        i, arr_len = 0, len(arr)
        # 构造大顶堆,从非叶子节点开始倒序遍历
        for i in range(int(arr_len / 2 - 1), -1, -1):
            self.build_heap(i, arr_len - 1, arr)
        for j in range(arr_len - 1, 0, -1):
            # 将堆顶元素与最后一个元素进行交换,除去最后一个元素外可以组建为一个新的大顶堆
            arr[0], arr[j] = arr[j], arr[0]
            # 将剩下的元素重新组建大顶堆
            self.build_heap(0, j - 1, arr)
        return arr

    def build_heap(self, i, len, arr):
        left, right = 2 * i + 1, 2 * i + 2
        large_index = i
        if left <= len and arr[i] < arr[left]:
            large_index = left
        if right <= len and arr[left] < arr[right]:
            large_index = right
        if large_index != i:
            arr[i], arr[large_index] = arr[large_index], arr[i]
            self.build_heap(large_index, len, arr)
            

面试中经常考的一个面试题就是,如果在海量数据中找出最大的100个数字,看到这个问题,可能大家首先会想到的是使用高效排序算法,比如快排,对这些数据排序,时间复杂度是O(nlogn),然后取出最大的100个数字。但是如果数据量很大,一个机器的内存不足以一次过读取这么多数据,就不能使用这个方法了。

不使用分布式机器计算,使用一个机器也能找出TopK的经典算法就是使用堆排序了,具体方法是:

维护一个大小为 K 的小顶堆,依次将数据放入堆中,当堆的大小满了的时候,只需要将堆顶元素与下一个数比较:

如果小于堆顶元素,则直接忽略,比较下一个元素;
如果大于堆顶元素,则将当前的堆顶元素抛弃,并将该元素插入堆中。遍历完全部数据,Top K 的元素也自然都在堆里面了。

堆排序很多内容来自于知乎博客,原文可参考下面链接,原博主在堆排序介绍的更加详细堆排序

写在后面

博主创作不易,无论是找资料还是写代码都是需要花费时间和精力的,茫茫人海,如果你看到了我的博客,觉得写的还行的话,希望能点赞支持一下,让我更有创作的动力。
在这里插入图片描述

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值