热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

牛B三人组快速排序堆排序归并排序

快速排序随便取个数,作为标志值,这里就默认为索引位置为0的值记录左索引和右索引,从右往左找比标志值小的,小值和左索引值交换&

快速排序

  • 随便取个数,作为标志值,这里就默认为索引位置为0的值
  • 记录左索引和右索引,从右往左找比标志值小的,小值和左索引值交换,右索引变化,然后从左往右找比标志值大的,大值和右索引值交换,左索引变化
  • 循环第二步骤直到左索引和右索引碰头,标志值和当期左索引(右)交换,这样一个循环下,就得出一个标志值左边都比它小,右边都比大的数据样本
  • 利用递归,对数据进行上述过程的最终标志值索引分割,分割到递归底层只有两个数,那么上述过程排序就一定有序了

  实现要点:随机取标志值,循环右取小、左取大,利用左右索引碰头位置进行递归分割

def partition(li, left, right):tmp = li[left]while left = tmp: #从右面找比tmp小的数right -= 1 # 往左走一步li[left] = li[right] #把右边的值写到左边空位上# print(li, 'right')while left

   快速排序一般情况很快,但是遇到最坏情况(倒序的情况),算法复杂度为O(n2),最好的情况(正序),算法复杂度为O(n)

  快速排序有可能超过最大递归深度 

 

堆排序

  堆排序难点就是有一堆的概念需要你理解,开始前,那就必须讲讲概念了

  树结构:我们程序见到的结构很像生活中的树,不过这里的是倒挂的,根在上,叶子在下,而根,在结构中,我们称为根节点,叶子称为叶子节点,中间的为枝节点

  满二叉树和完全二叉树:

  • 二叉树,就是每个节点最多两个枝节点或叶子节点
  • 深度k,数下树有多少层,比如下图就是深度为4

  • 满二叉树,除最后一层叶子节点,其他层节点都有两个子节点,节点数满足2^k-1

 

  • 完全二叉树,节点数满足至少有2k-1个,至多有2k-1个,最后一层叶子节点可缺,但是这个缺,要连续缺,比如上图,缺7或缺67或缺567

 

  大根堆和小根堆:

  • 大根堆:满足父节点都比子节点大的完全二叉树

 

  • 小根堆:满足父节点都比子节点小的完全二叉树

 

  树的存储:存储时,我们用的就是列表存储,不过你会想,那怎么体现树的结构在里面的呢?从根节点开始,根节点放入索引位置为0的地方,下一层,从左为右依次放入,就如下图

  

  树的存储规律:

  • 已知父节点位置为i,获取左子节点位置为:2i+1,获取右子节点位置为:2i+2
  • 已知子节点位置为i,获取父节点:无论这个子节点是左子还是右子,(i-1) // 2

  堆的向下调整和建堆

  由于刚开始拿到堆并不满足大根堆(大根堆用于从小到大排序,因为每次取完根节点最大数都是放在树的最后位置,也就是列表的最后位置,小根堆则用于从大到小排序)的情况,所以还需要了解堆的向下调整和建堆

  • 堆的向下调整,如下图,刚开始堆不满足大根堆,因为不满足根节点30比47,91大,所以需要进行向下调整,第一步:左右子节点比较,91大,并且大于根节点,发生位置交换    第二步:30下一层左右子节点比较,85大,也比30大,发生位置交换

  经过上面过程,此时的堆就是大根堆了,不过这个调整过程有个前提,就是根节点下的子堆已经满足大根堆的条件,建立这个条件,我们叫建堆

 

  • 建堆:过程就要从底层的堆开,好比民主选择样,先从村选村长,再从村长中选县长,层层推举上去,如下图

  第一步:85-91堆选举,91大,当村长,91目前就是村长,不用换

  第二步:12-24-30堆选举,30大,当县长,情况满足不用换

  第三步:85-47-91-36堆选举,91大,当县长,36-91交换,而且36比85小,村长也当不了,85-36交换,该过程就是向下调整的过程,村级对满足大根堆条件

  第四步:整个堆推选市长,53小,又是向下调整的过程

  所以建堆本质上也就是小堆基础上进行向下调整就能达到建堆的目的

 

  代码实现要点:

  • 堆向下调整:堆调整的上下边界,循环过程从2i+1左子节点开始,左右(前提是有右子)子节点比较大小-然后和父节点值比较确定是否交换
  • 建堆:确定最后叶子节点(n-1)的父节点((n-2) // 2), 倒序循环调用向下调整
  • 取数:根节点数与最后位置发生交换,调用向下调整(注意下边界high的变化,排除取好的最大数在调整范围)

def sift(li, low, high):""":param li: 列表:param low: 堆的根节点位置:param high: 堆的最后一个元素的位置:return: """i &#61; low # i最开始指向根节点j &#61; 2 * i &#43; 1 # j开始是左孩子tmp &#61; li[low] # 把堆顶存起来while j <&#61; high: # 只要j位置有数if j &#43; 1 <&#61; high and li[j&#43;1] > li[j]: # 如果右孩子有并且比较大j &#61; j &#43; 1 # j指向右孩子if li[j] > tmp:li[i] &#61; li[j]i &#61; j # 往下看一层j &#61; 2 * i &#43; 1else: # tmp更大&#xff0c;把tmp放到i的位置上li[i] &#61; tmp # 把tmp放到某一级领导位置上breakelse:li[i] &#61; tmp # 把tmp放到叶子节点上def heap_sort(li):n &#61; len(li)for i in range((n-2)//2, -1, -1):# i表示建堆的时候调整的部分的根的下标sift(li, i, n-1)# 建堆完成了for i in range(n-1, -1, -1):# i 指向当前堆的最后一个元素li[0], li[i] &#61; li[i], li[0]sift(li, 0, i - 1) #i-1是新的highli &#61; [i for i in range(100)]
import random
random.shuffle(li)
print(li)heap_sort(li)
print(li)

  利用堆排序解决topK问题

  思路&#xff1a;需要多少k&#xff0c;就建立以k个节点的小根堆&#xff0c;循环剩下数&#xff0c;如果比当前堆的根节点大&#xff0c;放入堆中&#xff0c;进行向下调整

def sift(li, low, high):i &#61; lowj &#61; 2 * i &#43; 1tmp &#61; li[low]while j <&#61; high:if j &#43; 1 <&#61; high and li[j&#43;1] heap[0]:heap[0] &#61; li[i]sift(heap, 0, k-1)# 2.遍历for i in range(k-1, -1, -1):heap[0], heap[i] &#61; heap[i], heap[0]sift(heap, 0, i - 1)# 3.出数return heapimport random
li &#61; list(range(1000))
random.shuffle(li)print(topk(li, 10))

  

归并排序

  归并排序的原理是两个已经有序的列表合并为大的有序列表&#xff0c;合并过程中&#xff0c;两个列表各自最小的数进行比较&#xff0c;把小的放入到一个新的列表

  归并排序分为两个过程&#xff1a;拆分过程和合并过程&#xff0c;拆分过程好弄&#xff0c;就按一半一半的拆&#xff0c;直到底层为一个数的列表&#xff0c;此时开始合并&#xff0c;此时合并的前提--两个有序的列表已经满足

  代码实现点&#xff1a;利用递归一半一半的分&#xff0c;合并&#xff1a;确定两个列表的边界范围&#xff0c;两个各取最小数进行比较-小的添加到新列表-对应的索引变化

  注意&#xff1a;肯定有一边的数因为普遍小&#xff0c;先循环完&#xff0c;所以最后只要还有数的列表进行循环添加就可以了

def merge(li, low, mid, high):i &#61; lowj &#61; mid &#43; 1ltmp &#61; []while i<&#61;mid and j<&#61;high: # 只要左右两边都有数if li[i] # merge(li, 0, 3, 7)
# print(li)def merge_sort(li, low, high):if low import random
random.shuffle(li)
print(li)
merge_sort(li, 0, len(li)-1)
print(li)

  

转:https://www.cnblogs.com/xinsiwei18/p/10129182.html



推荐阅读
  • 十大经典排序算法动图演示+Python实现
    本文介绍了十大经典排序算法的原理、演示和Python实现。排序算法分为内部排序和外部排序,常见的内部排序算法有插入排序、希尔排序、选择排序、冒泡排序、归并排序、快速排序、堆排序、基数排序等。文章还解释了时间复杂度和稳定性的概念,并提供了相关的名词解释。 ... [详细]
  • 阿里Treebased Deep Match(TDM) 学习笔记及技术发展回顾
    本文介绍了阿里Treebased Deep Match(TDM)的学习笔记,同时回顾了工业界技术发展的几代演进。从基于统计的启发式规则方法到基于内积模型的向量检索方法,再到引入复杂深度学习模型的下一代匹配技术。文章详细解释了基于统计的启发式规则方法和基于内积模型的向量检索方法的原理和应用,并介绍了TDM的背景和优势。最后,文章提到了向量距离和基于向量聚类的索引结构对于加速匹配效率的作用。本文对于理解TDM的学习过程和了解匹配技术的发展具有重要意义。 ... [详细]
  • CSS3选择器的使用方法详解,提高Web开发效率和精准度
    本文详细介绍了CSS3新增的选择器方法,包括属性选择器的使用。通过CSS3选择器,可以提高Web开发的效率和精准度,使得查找元素更加方便和快捷。同时,本文还对属性选择器的各种用法进行了详细解释,并给出了相应的代码示例。通过学习本文,读者可以更好地掌握CSS3选择器的使用方法,提升自己的Web开发能力。 ... [详细]
  • 欢乐的票圈重构之旅——RecyclerView的头尾布局增加
    项目重构的Git地址:https:github.comrazerdpFriendCircletreemain-dev项目同步更新的文集:http:www.jianshu.comno ... [详细]
  • STL迭代器的种类及其功能介绍
    本文介绍了标准模板库(STL)定义的五种迭代器的种类和功能。通过图表展示了这几种迭代器之间的关系,并详细描述了各个迭代器的功能和使用方法。其中,输入迭代器用于从容器中读取元素,输出迭代器用于向容器中写入元素,正向迭代器是输入迭代器和输出迭代器的组合。本文的目的是帮助读者更好地理解STL迭代器的使用方法和特点。 ... [详细]
  • 面试经验分享:华为面试四轮电话面试、一轮笔试、一轮主管视频面试、一轮hr视频面试
    最近有朋友去华为面试,面试经历包括四轮电话面试、一轮笔试、一轮主管视频面试、一轮hr视频面试。80%的人都在第一轮电话面试中失败,因为缺乏基础知识。面试问题涉及 ... [详细]
  • {moduleinfo:{card_count:[{count_phone:1,count:1}],search_count:[{count_phone:4 ... [详细]
  • 本文介绍了使用PHP实现断点续传乱序合并文件的方法和源码。由于网络原因,文件需要分割成多个部分发送,因此无法按顺序接收。文章中提供了merge2.php的源码,通过使用shuffle函数打乱文件读取顺序,实现了乱序合并文件的功能。同时,还介绍了filesize、glob、unlink、fopen等相关函数的使用。阅读本文可以了解如何使用PHP实现断点续传乱序合并文件的具体步骤。 ... [详细]
  • 本文详细介绍了Linux中进程控制块PCBtask_struct结构体的结构和作用,包括进程状态、进程号、待处理信号、进程地址空间、调度标志、锁深度、基本时间片、调度策略以及内存管理信息等方面的内容。阅读本文可以更加深入地了解Linux进程管理的原理和机制。 ... [详细]
  • 计算成像的原理与应用研究
    本文探讨了计算成像的原理与应用研究。首先介绍了小孔成像实验和软件方面的相关内容。随后从傅里叶光学的角度简单谈了成像的过程。成像是观测样品分布的一种方法,通过成像系统接收光的强度来呈现图像。视网膜作为接收端接收到的图像实际上是由像元组成的矩阵,每个元素代表相应位置像元接收光的强度。大脑通过对图像的分析,得出一系列信息,如识别物体、判断距离等。计算成像是一种采集记录系统,通过处理数据得到样品分布与像的对应关系,用于后续问题的分析。 ... [详细]
  • 浏览器中的异常检测算法及其在深度学习中的应用
    本文介绍了在浏览器中进行异常检测的算法,包括统计学方法和机器学习方法,并探讨了异常检测在深度学习中的应用。异常检测在金融领域的信用卡欺诈、企业安全领域的非法入侵、IT运维中的设备维护时间点预测等方面具有广泛的应用。通过使用TensorFlow.js进行异常检测,可以实现对单变量和多变量异常的检测。统计学方法通过估计数据的分布概率来计算数据点的异常概率,而机器学习方法则通过训练数据来建立异常检测模型。 ... [详细]
  • 词袋模型的通俗介绍
    词,袋, ... [详细]
  • #define_CRT_SECURE_NO_WARNINGS#includelist.h#includevoidSListInit(PNode*pHead ... [详细]
  • Python教学练习二Python1-12练习二一、判断季节用户输入月份,判断这个月是哪个季节?3,4,5月----春 ... [详细]
  • 花瓣|目标值_Compose 动画边学边做夏日彩虹
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了Compose动画边学边做-夏日彩虹相关的知识,希望对你有一定的参考价值。引言Comp ... [详细]
author-avatar
mobiledu2502917563
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有