详解快速排序和堆排序手撕代码思路【golang】

您所在的位置:网站首页 堆排序与快速排序 详解快速排序和堆排序手撕代码思路【golang】

详解快速排序和堆排序手撕代码思路【golang】

2024-07-12 05:13| 来源: 网络整理| 查看: 265

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录 前言一、快速排序和堆排序的使用场景和思路1、快速排序2、堆排序 二、手撕代码思路(golang,代码均为博主实测正确,请放心食用)1.快速排序2.堆排序 三、稳定性及时间复杂度1、快速排序2、堆排序 总结

前言

最近在面试中遇到了许多排序相关的题目,也被面试官要求过手撕快排、堆排代码,今天和大家分享一下golang的快排、堆排的手撕代码思路,如果有更好的思路,欢迎评论或者私信作者,我们一起讨论

一、快速排序和堆排序的使用场景和思路 1、快速排序

使用场景:绝大部分通用场景,go的sort包,C++的stl库中的sort包。当然快排只是这些排序包中的主要算法,C++和go的sort包为了提升实际效率,还结合了插入排序(希尔排序)、堆排序等等。 算法思路:快排的中心思想是分治法,每轮选出一个基准值,将大于基准值的元素放在基准值右边,将小于基准值的元素放到基准值的左边,那么每一轮我们就确定了基准值的具体位置,下一轮将基准值左边的元素们和基准值右边的元素们再分别确定出下一轮的基准值的位置,直到基准值两侧的元素个数均为1,此时显然已经确定出它们自身的位置,排序完毕

2、堆排序

使用场景:TopK问题,即取出数组中最大/最小的k个元素的问题,因此堆排序在实际应用中并不会完成数组的全部有序,往往在拿出k个实际问题所需要的值后就结束,我们在掌握堆排序时不应该只停留于默写代码,更要明白实际问题中如何去应用它(文章最后给大家留了算法题,有时间的同学可以思考并coding一下),还有一些增删改查频率较高的问题也需要运用到堆排序解决问题。 算法思路:堆其实是一颗父节点大于/小于左右子节点的完全二叉树,父节点大于子节点的堆称为大顶堆,父节点小于子节点的堆称为小顶堆。以大顶堆为例,在建堆和调整堆的过程中,我们发现子节点大于父节点时,需要交换父节点与子节点,由于交换后,父节点并不能保证比子节点的子节点更大,因此还需要递归向下比较。当建堆/调整堆完成后,堆顶元素(二叉树的根节点)即为堆中的最大值,我们把最大值取出并重新调整出元素数量为n-1的新大顶堆,再次取出最大值,n轮过后,所有元素都被依次取出,排序完毕

二、手撕代码思路(golang,代码均为博主实测正确,请放心食用) 1.快速排序

思路(配合代码一起看):维护两个变量 low和high,分别作为本轮快速排序的最小、最大下标,基准值p=nums[(low+high)/2],即中间值(此处取low,high间的任意值均可,取中间值只是常规思路,实际使用可以根据业务场景做变化),开始遍历low,high间的元素,使用两个指针left、right,其初始值为low,high,left向右递增,right向左递减,从左往右,找到一个大于等于基准值的元素,从右往左,找到一个小于等于基准值的元素(此过程中要保证left= high { return } left, right := low, high p := nums[(low+high)/2] for left



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3