数据结构与算法--二叉树第k个大的节点

二叉树第k个大的节点

  • 二叉树文章列表:

数据结构与算法–面试必问AVL树原理及实现

数据结构与算法–二叉树的深度问题

数据结构与算法–二叉堆(最大堆,最小堆)实现及原理

数据结构与算法–二叉查找树转顺序排列双向链表

数据结构与算法-- 二叉树中和为某一值的路径

数据结构与算法-- 二叉树后续遍历序列校验

数据结构与算法-- 广度优先打印二叉树

数据结构与算法–解决问题的方法- 二叉树的的镜像

数据结构与算法–重建二叉树

数据结构与算法–二叉查找树实现原理

数据结构与算法–二叉树实现原理

数据结构与算法–B树原理及实现

数据结构与算法–数字在排序数组中出现次数

数据结构与算法–死磕二叉树

数据结构与算法–二叉树第k个大的节点

数据结构与算法–求1~n能组成的所有二叉搜索树的排列

  • 之前遇到过多个类型的题型但是都是针对数组这种数据结构,如果两篇:

数据结构与算法–最小的k个数
数据结构与算法–查找与排序另类用法-旋转数组中的最小数字

  • 其中最小k个数我们用二分法的思路,很快得出解,还有就是用二叉堆的特性求解
  • 在旋转数组中查找最小值,直接二分查找完成
  • 由上可见,二分法在数组中查找第k个大小的数还是很好用的。但是我们此处针对的是二叉排序树,二分法可能排不上用处

方法一统计节点法

  • 利用二叉排序数的特性,左节点 比 根小, 右节点比根大,那么需要找第 k 大的,直接统计左右节点个数

    • 如果右边节点个数 rightCount > k,那么第k 大的必然在右节点
    • 如果右节点个数 rightCount < k,那么有两种情况:
      • 当rightCount < k, 并且rightCount - k = 1 此时,最大的就是当前根节点
      • 如果rightCount < k,并且rigntCount- k > 1 此时,那么第 k 大的节点就是左节点的 k - rightCount - 1 个大的节点
  • 我们依次筛选左右节点,直到找到k 的具体节点,或者父节点,将k范围缩小到1或 0

  • 当k = 1 ,就是最右节点,当k = 0 就是最左节点。我们用如下图实例

  • 情况一:正好是root节点情况
    在这里插入图片描述

  • 情况二:在left节点中在这里插入图片描述
    在这里插入图片描述

  • 情况三,在right节点中
    在这里插入图片描述

  • 经如上分析有如下代码:

/*** 二叉搜索树中查找第 k 大的节点** @author liaojiamin* @Date:Created in 10:18 2021/7/16*/
public class FinMaxKNumberInBinary {public static void main(String[] args) {BinaryNode node = new BinaryNode(null, null, null);BinarySearchTree searchTree = new BinarySearchTree();Random random = new Random();for (int i = 0; i < 5; i++) {node = searchTree.insert(random.nextInt(100), node);}searchTree.printTree(node);System.out.println();System.out.println(getMaxKNumber(node, 4).getElement());}/*** 遍历统计,在比较*/public static BinaryNode getMaxKNumber(BinaryNode binaryNode, Integer k) {if (binaryNode == null || k < 0) {return null;}if (k == 1) {BinaryNode right = binaryNode;while (right.getRight() != null) {right = right.getRight();}return right;}if (k == 0) {BinaryNode left = binaryNode;while (left.getLeft() != null) {left = left.getLeft();}return left;}BinaryNode baseCount = new BinaryNode(null, null, null);baseCount.setCount(0);int rightCount = countNode(binaryNode.getRight(), baseCount).getCount();//第k大的在rightif (rightCount >= k) {return getMaxKNumber(binaryNode.getRight(), k);}//此时root节点是当前第 k大的数据if (k - rightCount == 1) {return binaryNode;}//第k大的在leftif (k - rightCount > 1) {return getMaxKNumber(binaryNode.getLeft(), k - rightCount - 1);}return null;}public static BinaryNode countNode(BinaryNode binaryNode, BinaryNode baseCount) {if (binaryNode == null) {return baseCount;}baseCount.setCount(baseCount.getCount() + 1);countNode(binaryNode.getLeft(), baseCount);countNode(binaryNode.getRight(), baseCount);return baseCount;}
}
  • 以上实现方案中通过递归不断将 第 k大的节点范围缩小,在最后的2个节点中找出我们的值,问题在于,存在太多重复的遍历,如上情况三种:
  • 当遍历右子树 C的时候其实已经遍历过 G,F
  • 但是在之后的步骤中还依然需要遍历G, F继续缩小范围,因此时间效率很低

方法二逆中序遍历

  • 还是利用二叉搜索树的特性,我们需要找最大的第 k位置,但是在二叉树三种遍历方式中,前序,中序,后续遍历,只有中序遍历是按顺序排列二叉搜索树的所有节点,但是是小到大的顺序
  • 由此我们得到启发:
    • 我们利用中序遍历,求第k个大的,也就是从小到大排列的第 s - k+ 1 个数据,但是此时我们并不知道二叉树的总节点,无法得出这个值
    • 如果我们反过来遍历,中序遍历是 左,中,右, 我们换成 右,根,左,那么直接求第k个位置的遍历到的节点就得到我们的解
  • 因此最简单的遍历查找方式如下
/*** 二叉搜索树中查找第 k 大的节点** @author liaojiamin* @Date:Created in 10:18 2021/7/16*/
public class FinMaxKNumberInBinary {public static void main(String[] args) {BinaryNode node = new BinaryNode(null, null, null);BinarySearchTree searchTree = new BinarySearchTree();Random random = new Random();for (int i = 0; i < 5; i++) {node = searchTree.insert(random.nextInt(100), node);}searchTree.printTree(node);System.out.println();System.out.println(getMaxKNumber(node, 4).getElement());System.out.println(getMaxKNumberOver(node, 4).getElement());}/*** 直接从最大的遍历,同时统计遍历节点数,当统计到k个,则是第k个大*/public static BinaryNode getMaxKNumberOver(BinaryNode binaryNode, Integer k) {if (binaryNode == null || k < 0) {return null;}BinaryNode baseCount = new BinaryNode(null, null, null);baseCount.setCount(0);return printOver(binaryNode, baseCount, k);}/*** 右, 中,  左,方式遍历树,与之前树遍历三种都不同*/public static BinaryNode printOver(BinaryNode node, BinaryNode baseCount, Integer k) {if(node == null){return baseCount;}baseCount = printOver(node.getRight(), baseCount, k);baseCount.setCount(baseCount.getCount() + 1);if(baseCount.getCount() == k){baseCount = node;baseCount.setCount(k);return  baseCount;}return printOver(node.getLeft(), baseCount, k);}
}

上一篇:数据结构与算法–再来聊聊数组
下一篇:数据结构与算法–求1~n能组成的所有二叉搜索树的排列

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/310305.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Istio 中的 Sidecar 注入及透明流量劫持过程详解

图片来源&#xff1a;上海五角场 by Jimmy Song本文基于 Istio 1.5.1 版本&#xff0c;将为大家介绍以下内容&#xff1a;什么是 sidecar 模式和它的优势在哪里。Istio 中是如何做 sidecar 注入的&#xff1f;Sidecar proxy 是如何做透明流量劫持的&#xff1f;流量是如何路由到…

数据结构与算法--求1~n能组成的所有二叉搜索树的排列

给定一个整数n&#xff0c;生成并返回所有N个节点组成并且节点值从1到n互不相同的不同二叉树&#xff0c;可以按照任意顺序 二叉树文章列表&#xff1a; 数据结构与算法–面试必问AVL树原理及实现 数据结构与算法–二叉树的深度问题 数据结构与算法–二叉堆&#xff08;最大…

Java语法基础50题训练(下)

题目1: HashMap集合存储学生对象并遍历。 需求: 创建一个HashMap集合&#xff0c;键是学生对象(Student)&#xff0c;值是居住地(String)。存储多个键值对象&#xff0c;并遍历。 要求: 保证键的唯一性&#xff1a;如果学生对象的成员变量值相同&#xff0c;我们就认为是同一…

用long类型让我出了次生产事故,写代码还是要小心点

昨天发现线上试跑期的一个程序挂了&#xff0c;平时都跑的好好的&#xff0c;查了下日志是因为昨天运营跑了一家美妆top级淘品牌店&#xff0c;会员量近千万&#xff0c;一下子就把128G的内存给爆了&#xff0c;当时并行跑了二个任务&#xff0c;没辙先速写一段代码限流&#x…

Mongodb查询分析器解析

Mongodb查询分析器 动态相关项目中涉及到数据量大和吞吐量的接口&#xff0c;例如关注页面动态&#xff0c;附近动态&#xff0c;这部分数据都是存储在mongodb中&#xff0c;在线上数据中分类两个mongodb集合存储其中关注动态基于扩散写的设计&#xff0c;数据量已经快到 8 亿…

[Java基础]Collections概述和使用

代码如下: package CollectionDemo01;import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List;public class CollectionDemo01 {public static void main(String[] args){List<Integer> list new ArrayList&l…

链路追踪在ERP系统中的应用实践

源宝导读&#xff1a;随着ERP的部署架构越来越复杂&#xff0c;对运维监控、问题排查等工作增加了难度&#xff0c;本文将介绍通过引入链路追踪技术&#xff0c;提高ERP系统问题排查效率&#xff0c;支撑更全面监控系统运行情况的实践过程。一、导读随着ERP的部署架构越来越复杂…

[Java基础]File基础

File类概述和构造方法: 代码如下: package FileStudyPack;import java.io.File;public class FileDemo01 {public static void main(String[] args){File f1 new File("D:\\JavaDemo\\java.txt");System.out.println(f1);File f2 new File("D:\\JavaDemo&quo…

java 日志乱码_【开发者成长】JAVA 线上故障排查完整套路!

云栖号资讯&#xff1a;【点击查看更多行业资讯】在这里您可以找到不同行业的第一手的上云资讯&#xff0c;还在等什么&#xff0c;快来&#xff01;线上故障主要会包括 CPU、磁盘、内存以及网络问题&#xff0c;而大多数故障可能会包含不止一个层面的问题&#xff0c;所以进行…

谈谈登录密码传输这件小事

背景 大大小小的系统其实都离不开登录这个小小的功能&#xff0c;前段时间老黄在审查公司部分系统代码时&#xff0c;发现不少系统的登录还是很粗暴的&#xff0c;粗暴到让人不敢说话的那种。说到登录&#xff0c;结合标题&#xff0c;其实大部分人应该都猜到那个粗暴到让人不敢…

技术分享杂七杂八技术

技术分享 听花谷 距离名宿 6~7 公里左右&#xff0c;丽江网红基地&#xff0c;有举办婚礼的地方听花谷&#xff0c;坐落于玉龙雪山脚下&#xff0c;前有玉龙雪山&#xff0c;后有原始森林。园内共有三处白色空间&#xff0c;第一处共有三层&#xff0c;婚礼举行&#xff0c;发…

java 操作日志设计_日志系统新贵 Loki,确实比笨重的ELK轻

本文同步Java知音社区&#xff0c;专注于Java作者&#xff1a;linkt1234http://blog.csdn.net/Linkthaha/article/details/100575278最近&#xff0c;在对公司容器云的日志方案进行设计的时候&#xff0c;发现主流的ELK或者EFK比较重&#xff0c;再加上现阶段对于ES复杂的搜索功…

Istio1.5 Envoy 数据面 WASM 实践

Istio 1.5 回归单体架构&#xff0c;并抛却原有的 out-of-process 的数据面扩展方式&#xff0c;转而拥抱基于 WASM 的 in-proxy 扩展&#xff0c;以期获得更好的性能。本文基于网易杭州研究院轻舟云原生团队的调研与探索&#xff0c;介绍 WASM 的社区发展与实践。超简单版解释…

elasticSearch -- (文档,类型,索引)

问题:大规模数据如何检索 当系统数据量达到10亿&#xff0c;100亿级别的时候&#xff0c;我们系统该如何去解决这种问题。 数据库选择—mysql&#xff0c; sybase&#xff0c;oracle&#xff0c;mongodb&#xff0c;hbase…单点故障如何解决—lvs&#xff0c; F5&#xff0c;…

asp后台调用产品数据_后台产品经理,需掌握这些数据交互知识

人们每天都在接收信息和发送信息&#xff0c;在传递信息的过程中&#xff0c;明白对方要表达的意思。数据也是如此&#xff0c;在系统交换数据的过程中&#xff0c;就伴随着数据交互。本篇文章将为大家具体分析前端和后台的数据交互与协议。本文所说的”数据交换” 是指在计算机…

使用c# .net core开发国标gb28181 sip +流媒体服务完成视频监控实例教程 亲身完美体验过程...

目前使用C# .net core 来实现国标gb28181标准的摄像头播放、ptz云台控制、视频回放等视频监控功能&#xff0c;项目可运行于linux/docker/.net core环境&#xff0c;也是当前非常罕有的能做到毫秒级国标gb28181公网视频传送案例&#xff0c;也是少有的能同时具有播放、ptz云台控…

[Java基础]字节流读数据

代码如下: package InstreamPack;import java.io.FileInputStream; import java.io.IOException;public class FileInputStreamDemo01 {public static void main(String[] args) throws IOException {FileInputStream fis new FileInputStream("D:\\JavaDemo\\java.txt&…

丁可以组什么词_有哪些量词可以用来描述生意经?

分别有&#xff1a;本&#xff0c; 一(本)生意经。笔&#xff0c; 一(笔)生意经。次&#xff0c;一(次)生意量词用名量词&#xff1a;表示事物的计量单位。基本定义&#xff1a;通常用来表示人、事物或动作的数量单位的词&#xff0c;叫做量词。量词 lingc&#xff0c;与代表可…