news 2026/2/27 4:47:52

树的初阶相关知识(下)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
树的初阶相关知识(下)

https://blog.csdn.net/qscftqwe/article/details/155913703

这是上节课的知识,大家可以点进去看一下!

一.复盘树的初阶相关知识(上)的题目

1.下列关键字序列为堆的是:() A 100,60,70,50,32,65 B 60,70,65,50,32,100 C 65,100,70,32,50,60 D 70,65,100,32,50,60 E 32,50,100,70,65,60 F 50,100,70,65,60,32 2.已知小根堆为8,15,10,21,34,16,12,删除关键字 8 之后需重建堆,在此过程中 关键字之间的比较次数是()。 A 1 B 2 C 3 D 4 3.一组记录排序码为(5 11 7 2 3 17),则利用堆排序方法建立的初始堆为 A(11 5 7 2 3 17) B(11 5 7 2 17 3) C(17 11 7 2 3 5) D(17 11 7 5 3 2) E(17 7 11 3 5 2) F(17 7 11 3 2 5) 4.最小堆[0,3,2,5,7,4,6,8],在删除堆顶元素0之后,其结果是() A[3,2,5,7,4,6,8] B[2,3,5,7,4,6,8] C[2,3,4,5,7,8,6] D[2,3,4,5,6,7,8] 1.A 2.C 3.C 4.C

通过上节课的知识,我们就能轻松把这几题搞定,如果做不出来你可以去看看我上节课的内容,那个对堆的理解有很大的帮助!

二.建堆时间复杂度

当我们学习这个,我们就知道为什么建堆采用的是向下建堆而不是向上建堆!

因为堆是完全二叉树,而满二叉树也是完全二叉树,此处为了简化使用满二叉树来证明(时间复杂度本来看的就是近似值,多几个节点不影响最终结果)

这张图是分析向下建堆的推导过程,至于这个图我就不和大家分析了,我也有点看不懂,如果你也看不懂,可以看一下我的大白话解析,当然我相信大家肯定都能看懂上面的拉!

首先向下建堆它的优势是不需要对最底层(叶子节点)进行调整,而二叉树的最后一层节点就差不多是总结的的一半,因此向下建堆就减少了一半的工作量,而这减少一半的工作量就是从O(nlogn)降到O(n),好了我实在编不下去了,不过理倒是这个理,大家如果想知道为什么去看看别人吧,我实在是做不到!

三.堆的应用

我们讲了堆,那么它到底有什么作用呢?

关于它最大的作用其实是讲解TOP-K问题,那什么是TOP-K问题呢?

TOP-K问题:即求数据结合中前K个最大的元素或者最小的元素,一般情况下数据量都比较大

比如:专业前10名、世界500强、富豪榜、游戏中前100的活跃玩家等。

堆解决的基本思路:

1.用数据集合中前K个元素来建堆:

前k个最大的元素,则建小堆

前k个最小的元素,则建大堆

2.用剩余的N-K个元素依次与堆顶元素来比较,不满足则替换堆顶元素

将剩余N-K个元素依次与堆顶元素比完之后,堆中剩余的K个元素就是所求的前K个最小或者最大的元素。

举个例子:假设我们有1000个元素,需要找出其中最大的前10个。首先构建一个包含10个元素的小顶堆,此时堆顶是这10个元素中最小的。剩下的990个元素依次与堆顶比较:如果比堆顶大,就替换堆顶元素并重新调整堆结构,使堆顶保持最小。这样不断筛选,最终堆中的10个元素就是最大的前10个。

四.二叉树链式结构的实现

4.1 二叉链

class BinaryTreeNode { public: int _data; BinaryTreeNode* _left;//左节点 BinaryTreeNode* _right;//右节点 };

二叉链的核心就是left和right,其分别代表着:左节点和右节点!

4.2 二叉树的遍历

学习二叉树结构,最简单的方式就是遍历。所谓二叉树遍历(Traversal)是按照某种特定的规则,依次对二叉树中的节点进行相应的操作,并且每个节点只操作一次。访问结点所做的操作依赖于具体的应用问题。 遍历是二叉树上最重要的运算之一,也是二叉树上进行其它运算的基础。

按照规则,二叉树的遍历有:前序/中序/后序的递归结构遍历

1. 前序遍历(Preorder Traversal 亦称先序遍历)——访问根结点的操作发生在遍历其左右子树之前。

2. 中序遍历(Inorder Traversal)——访问根结点的操作发生在遍历其左右子树之中。

3. 后序遍历(Postorder Traversal)——访问根结点的操作发生在遍历其左右子树之后。

这三种遍历我们通常均采用递归的方式完成。

#include<iostream> // 二叉树前序遍历 void PreOrder(Node* root) { if (root == nullptr) { return; } std::cout << root->_data << std::endl; PreOrder(root->_left); PreOrder(root->_right); } // 二叉树中序遍历 void InOrder(Node* root) { if (root == nullptr) { return; } InOrder(root->_left); std::cout << root->_data << std::endl; InOrder(root->_right); } // 二叉树后序遍历 void PostOrder(Node* root) { if (root == nullptr) { return; } PostOrder(root->_left); PostOrder(root->_right); std::cout << root->_data << std::endl; }

下面我通过一张图片带着大家来了解一下前序遍历,然后大家根据这个再去了解中序和后继!

前序遍历结果:1 2 3 4 5 6

中序遍历结果:3 2 1 5 4 6

后序遍历结果:3 2 5 6 4 1

4.3 层序遍历

层序遍历:除了先序遍历、中序遍历、后序遍历外,还可以对二叉树进行层序遍历。设二叉树的根节点所在层数为1,层序遍历就是从所在二叉树的根节点出发,首先访问第一层的树根节点,然后从左到右访问第2层上的节点,接着是第三层的节点,以此类推,自上而下,自左至右逐层访问树的结点的过程就是层序遍历。

#include<iostream> #include<queue> #include<assert.h> // 层序遍历 void LevelOrder(Node* root) { assert(root != nullptr);//树不为空 std::queue<Node*>q;//创建一个栈 q.push(root);//放入根节点 while (!q.empty()) { Node* node = q.front();//获取队列首元素 q.pop();//删除元素 if (node != nullptr)//该节点不为空,才能保证有左右节点外加数据 { //左节点不为空才放入 if (node->_left != nullptr) q.push(node->_left);//放入左节点 //右节点不为空才放入 if (node->_right != nullptr) q.push(node->_right);//放入右节点 std::cout << node->_data << std::endl;//打印节点 } } }

关于层序遍历还是需要和大家好好分析一下的!

首先层序遍历和之前提到的前中后遍历是不同阵营的,层序遍历的实现是更适合迭代,而前中后遍历更适合的是递归,因此这是二者的最大区别!

首先我们要保证先打印A——B——C,你想到了什么这不就是排队吗,那么排队我们用什么数据结构,大家肯定能想到队列,因此我们就创建一个队列,然后A生B和C,B生D和E,C再生F和G……明白这个我们就大概知道层序遍历的要点了,下面大家就可以根据我上面的代码来实现层序遍历了!

4.4 选择题

1.某完全二叉树按层次输出(同一层从左到右)的序列为 ABCDEFGH 。 该完全二叉树的前序序列为( ) A ABDHECFG B ABCDEFGH C HDBEAFCG D HDEBFGCA 2.二叉树的先序遍历和中序遍历如下:先序遍历:EFHIGJK;中序遍历: HFIEJKG.则二叉树根结点为() A E B F C G D H 3.设一课二叉树的中序遍历序列:badce,后序遍历序列:bdeca, 则二叉树前序遍历序列为____。 A adbce B decab C debac D abcde 4.某二叉树的后序遍历序列与中序遍历序列相同,均为 ABCDEF , 则按层次输出(同一层从左到右)的序列为() A FEDCBA B CBAFED C DEFCBA D ABCDEF 1.A 2.A 3.D 4.A

1:如果我们知道层序遍历,我们完全就可以把它画下来因此,此题没啥问题

2,3:这两题我们直接一起解决了,他们本质都是同一类题目,首先这类题这么做,首先它会给你两中遍历(其中必须有中序遍历)让你求第三个,为什么一定要知道中序,因为前序和后续我们只能知道根节点是那个,只有中序我们才知道左子树有那些,右子树有那些!

4:你用2,3的方法你同样可以解决,你会惊奇的发现这棵树就是一个丿(即该数的节点只可能有左孩子)

好了,今天的内容就到这里吧,很高兴能和大家分享这么多,如有不足多多包含,感谢大家了!

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/2/25 1:14:30

QT之简陋版网络调试助手

1. 开发流程 1.1 Qtcp服务器的关键步骤 • 工程建立&#xff0c;需要在.pro加入网络权限 • 创建一个基于 QTcpServer 的服务端涉及以下关键步骤&#xff1a; 1. 创建并初始化 QTcpServer 实例&#xff1a; • 实例化 QTcpServer 。 • 调用 listen 方法在特定端口监听传入的连…

作者头像 李华
网站建设 2026/2/27 9:08:27

【万字长文】深度思考RAG流水线:从零构建智能agent架构,小白必学,程序员必收藏的大模型应用指南!

简介 本文介绍了一种深度思考RAG流水线&#xff0c;通过agent驱动的架构解决复杂查询问题。系统将查询分解为多步骤计划&#xff0c;执行自适应检索策略&#xff0c;结合反思机制和自我评估循环&#xff0c;实现真正的多步推理。与传统线性RAG相比&#xff0c;该架构能处理多源…

作者头像 李华
网站建设 2026/2/21 21:47:43

从静态到动态:探索LLM和RAG在自动更新知识图谱中的协同效应

摘要 在AI应用中&#xff0c;知识图谱&#xff08;KG&#xff09;的实时更新至关重要&#xff0c;但现有KG如Wikidata和DBpedia往往手动维护或 infrequent 重建&#xff0c;导致信息过时。本文提出一种利用大语言模型&#xff08;LLM&#xff09;和检索增强生成&#xff08;RA…

作者头像 李华
网站建设 2026/2/25 0:14:40

抓住2026年AI黄金窗口!普通人也能实现月薪翻倍的转型全指南!

深夜&#xff0c;一家互联网大厂的HR正为一份特殊的Offer绞尽脑汁——如何用有竞争力的薪酬&#xff0c;吸引一位顶尖院校的AI算法博士。与此同时&#xff0c;另一位非技术出身的运营专员&#xff0c;却通过熟练掌握AI工具&#xff0c;成功将自己主导的项目效率提升了300%&…

作者头像 李华
网站建设 2026/2/24 6:21:51

BabylonJS开发:从入门到资深

目录 第一章&#xff1a;启航&#xff01;三维世界的入场券 1.1 WebGL与BabylonJS&#xff1a;你的浏览器里藏着一个宇宙 3D图形学极简史&#xff1a;从三角形到元宇宙 BabylonJS的“超能力清单”&#xff1a;为什么选它&#xff1f; 环境搭建&#xff1a;Node.js、TypeScr…

作者头像 李华
网站建设 2026/2/25 9:37:15

JavaScript概述

JavaScript概述 Js的书写方式主要有三种 行内式&#xff1a;在 HTML 标签中直接编写 <button onclick"alert(点击)">点我一下</button>内嵌式&#xff1a;通过 标签在 HTML 中嵌入 JS 代码 <body><script>alert(Hello JavaScript)</scrip…

作者头像 李华