当前位置: 首页 > news >正文

王道数据结构编程题 二叉树

二叉树定义

以下为本文解题代码的二叉树定义。

struct TreeNode {int val;TreeNode* left, *right;TreeNode(int val = 0, TreeNode* left = nullptr, TreeNode* right = nullptr): val(val), left(left), right(right) {}
};

非递归后序遍历

题目描述

编写后序遍历二叉树的非递归算法。

解题代码

void nonRecurPost(TreeNode* root) {if (root == nullptr) return;stack<TreeNode*> s;TreeNode* pre = nullptr;while (root != nullptr || !s.empty()) {while (root != nullptr) {s.emplace(root);root = root->left;}root = s.top();s.pop();if (root->right == nullptr || root->right == pre) {cout << root->val << " ";pre = root;root = nullptr;}else {s.emplace(root);root = root->right;}}
}

反向层序遍历

题目描述

试给出二叉树的自下而上、从右到左的层序遍历算法。

解题代码

void reOrderTraversal(TreeNode* root) {queue<TreeNode*> Q;stack<int> S;Q.emplace(root);while (!Q.empty()) {TreeNode* fNode = Q.front();S.emplace(fNode->val);Q.pop();if (fNode->left != nullptr) {Q.emplace(fNode->left);}if (fNode->right != nullptr) {Q.emplace(fNode->right);}}while (!S.empty()) {cout << S.top() << " ";S.pop();}
}

非递归计算高度

题目描述

假设二叉树采用二叉链表存储结构,设计一个非递归算法求二叉树的高度。

解题代码

int nonRecurHeight(TreeNode* root) {if (root == nullptr) return 0;int res = 0;queue<TreeNode*> q, nq;q.emplace(root);while (!q.empty()) {while (!q.empty()) {TreeNode* fNode = q.front();q.pop();if (fNode->left != nullptr) {nq.emplace(fNode->left);}if (fNode->right != nullptr) {nq.emplace(fNode->right);}}q = move(nq);++res;}return res;
}

根据中序和先序序列建立二叉树

题目描述

设一棵二叉树各结点的值互不相同,其先序遍历序列和中序遍历序列分别存储于两个一维数组 A 和 B 中,试编写算法建立该二叉树的二叉链表。

解题代码

	TreeNode* recurCreate(vector<int>& preOrder, int l1, int r1, vector<int>& inOrder, int l2, int r2) {if (l1 == r1) return nullptr;auto preBegin = preOrder.begin() + l1, preEnd = preOrder.begin() + r1;auto inBegin = inOrder.begin() + l2, inEnd = inOrder.begin() + r2;int x = *preBegin;TreeNode* root = new TreeNode(x);auto it = find(inBegin, inEnd, x);int lenL = it - inBegin;root->left = recurCreate(preOrder, l1 + 1, l1 + lenL + 1, inOrder, l2, l2 + lenL);root->right = recurCreate(preOrder, l1 + lenL + 1, r1, inOrder, l2 + lenL + 1, r2);return root;}TreeNode* createTree(vector<int>& preOrder, vector<int>& inOrder) {int l1 = 0, r1 = preOrder.size();int l2 = 0, r2 = inOrder.size();return recurCreate(preOrder, l1, r1, inOrder, l2, r2);}

判断完全二叉树

题目描述

二叉树按二叉链表形式存储,试编写一个判别给定二叉树是否是完全二叉树的算法。

解题代码

bool isCompleteBT(TreeNode* root) {queue<TreeNode*> Q;Q.emplace(root);bool isLeaves = false;while (!Q.empty()) {TreeNode* fNode = Q.front();Q.pop();if (fNode == nullptr) {isLeaves = true;continue;}if (isLeaves) return false;Q.emplace(fNode->left);Q.emplace(fNode->right);}return true;
}

计算双分支结点数

题目描述

假设二叉树采用二叉链表存储结构存储,试设计一个算法,计算一棵给定二叉树的所有双分支结点个数。

解题代码

int doubleNodeCnt(TreeNode* root) {if (root == nullptr) return 0;if (root->left != nullptr && root->right != nullptr) {return 1 + doubleNodeCnt(root->left) + doubleNodeCnt(root->right);}else {return doubleNodeCnt(root->left) + doubleNodeCnt(root->right);}
}

交换左右子树

题目描述

设树 B 是一棵采用链式结构存储的二叉树,编写一个把树 B 中所有结点的左右子树进行交换的算法。

解题代码

void swapLRNode(TreeNode* root) {if (root == nullptr) return;TreeNode* temp = root->left;root->left = root->right;root->right = temp;swapLRNode(root->left);swapLRNode(root->right);
}

先序序列第k个结点值

题目描述

假设二叉树采用二叉链表存储结构,设计一个算法,求先序遍历序列中第 k (1 <= k <= 链表中结点个数)个结点的值。

解题代码

int kthNodeVal(TreeNode* root, int& k) {if (root == nullptr) return 0;if (--k == 0) return root->val;return kthNodeVal(root->left, k) + kthNodeVal(root->right, k);
}

删除特定值的结点的子树

题目描述

已知二叉树以二叉链表形式存储,编写算法完成:对于树中的每个元素值为 x 的结点,删除以它为根的子树,并释放相应的空间。

解题代码

void freeMemory(TreeNode* root) {if (root == nullptr) return;freeMemory(root->left);freeMemory(root->right);delete root;
}void deleteXNode(TreeNode* root, int x) {if (root == nullptr) return;else if (root->val == x) {freeMemory(root);return;}if (root->left != nullptr && root->left->val == x) {freeMemory(root->left);root->left = nullptr;}if (root->right != nullptr && root->right->val == x) {freeMemory(root->right);root->right = nullptr;}deleteXNode(root->left, x);deleteXNode(root->right, x);
}

值为x的结点的祖先

题目描述

在二叉树中查找值为 x 的结点,试编写算法打印值为 x 的结点的所有祖先,假设值为 x 的结点的不多于一个。

解题代码

bool ancestorOfXNode(TreeNode* root, int x) {if (root == nullptr) return false;if (root->val == x) return true;bool left = ancestorOfXNode(root->left, x);bool right = ancestorOfXNode(root->right, x);if (left || right) {cout << root->val << " ";}return left || right;
}

两结点的最近公共祖先

题目描述

设 p 和 q 为指向二叉树中任意两个结点的指针,试编写算法找到 p 和 q 的最近公共祖先结点 r.

解题代码

TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {if (root == nullptr || root == p || root == q) return root;TreeNode* left = lowestCommonAncestor(root->left, p, q);TreeNode* right = lowestCommonAncestor(root->right, p, q);if (left != nullptr && right != nullptr) {return root;}else if (left != nullptr) {return left;}else {return right;}
}

二叉树的宽度

题目描述

假设二叉树采用二叉链表存储结构,设计一个算法,求非空二叉树 b 的宽度(即具有结点数最多的那一层的结点个数)。

解题代码

int widthOfBT(TreeNode* root) {if (root == nullptr) return 0;size_t res = 1;queue<TreeNode*> q, nq;q.emplace(root);while (!q.empty()) {while (!q.empty()) {TreeNode* fNode = q.front();q.pop();if (fNode->left != nullptr) {nq.emplace(fNode->left);}if (fNode->right != nullptr) {nq.emplace(fNode->right);}}q = move(nq);res = max(res, q.size());}return res;
}

满二叉树的后序序列

题目描述

设有一棵满二叉树(所有结点值均不同),已知其先序序列为 pre,设计一个算法求其后序序列 post.

解题代码

void getPost(vector<int>& preOrder, int p1, int q1, vector<int>& postOrder, int p2, int q2) {if (p1 > q1) return;postOrder[q2] = preOrder[p1];int mid = (q1 - p1) / 2;getPost(preOrder, p1 + 1, p1 + mid, postOrder, p2, p2 + mid - 1);getPost(preOrder, p1 + mid + 1, q1, postOrder, p2 + mid, q2 - 1);
}vector<int> postOfFBT(vector<int>& preOrder) {int n = preOrder.size();vector<int> res(n);getPost(preOrder, 0, n - 1, res, 0, n - 1);return res;
}

将叶结点连接为单链表

题目描述

设计一个算法将二叉树的叶结点按从左到右的顺序连成一个单链表,表头指针为 head,二叉树按照二叉链表形式存储。

解题代码

ListNode* linkingLeaves(TreeNode* root) {queue<TreeNode*> q;q.emplace(root);ListNode* dummy = new ListNode(-1);ListNode* curNode = dummy;while (!q.empty()) {TreeNode* fNode = q.front();q.pop();if (fNode->left == nullptr && fNode->right == nullptr) {curNode->next = new ListNode(fNode->val);curNode = curNode->next;}if (fNode->left != nullptr) {q.emplace(fNode->left);}if (fNode->right != nullptr) {q.emplace(fNode->right);}}return dummy->next;
}

相似二叉树

题目描述

试设计判断两棵二叉树是否相似的算法。所谓二叉树 T1 和 T2 相似,指的是 T1 和 T2 都是空的二叉树或都只有一个根节点;或者 T1 的左子树和 T2 的左子树是相似的,且 T1 的右子树和 T2 的右子树是相似的。

解题代码

bool similarBT(TreeNode* root1, TreeNode * root2) {if (root1 == nullptr && root2 == nullptr) return true;if ((root1 == nullptr) ^ (root2 == nullptr)) return false;if (root1->left == nullptr && root1->right == nullptr && root2->left == nullptr && root2->right == nullptr) {return true;}return similarBT(root1->left, root2->left) && similarBT(root1->right, root2->right);
}

二叉树的带权路径长度和

题目描述

二叉树的带权路径长度(WPL)是二叉树中所有叶结点的带权路径长度之和,给定一棵二叉树,其叶结点的 val 域保存该结点的非负权值。设 root 为指向 T 的根节点的指针,设计求 T 的 WPL 的算法。

解题代码

BFS

int getWPL(TreeNode* root) {queue<TreeNode*> q, nq;q.emplace(root);int res = 0;for (int len = 0; !q.empty(); ++len) {while (!q.empty()) {TreeNode* fNode = q.front();q.pop();if (fNode->left == nullptr && fNode->right == nullptr) {res += fNode->val * len;}if (fNode->left != nullptr) {nq.emplace(fNode->left);}if (fNode->right != nullptr) {nq.emplace(fNode->right);}}q = move(nq);}return res;
}

DFS

int dfs(TreeNode* root, int depth) {if (root == nullptr) return 0;if (root->left == nullptr && root->right == nullptr) {return root->val * depth;}return dfs(root->left, depth + 1) + dfs(root->right, depth + 1);
}int getWPL(TreeNode* root) {return dfs(root, 0);
}

表达式树转表达式

题目描述

请设计一个算法,将给定表达式树转换为对应的中缀表达式并输出。

解题代码

void dfs(TreeNode<char>* root, int depth) {if (root == nullptr) return;if (root->left == nullptr && root->right == nullptr) {cout << root->val;}else {if (depth > 1) cout << "(";dfs(root->left, depth + 1);cout << root->val;dfs(root->right, depth + 1);if (depth > 1) cout << ")";}
}void getInfixExp(TreeNode<char>* root) {dfs(root, 1);
}

判定顺序存储二叉树是否为二叉搜索树

题目描述

已知非空二叉树 T 结点值均为正整数,采用顺序存储方式存储,T 中不存在的结点在数组中用 -1 表示。请设计一个尽可能高效的算法,判定一棵采用这种方式存储的二叉树是否为二叉搜索树。

解题代码

bool dfs(vector<int>& T, int idx, int& lastVal) {if (idx - 1 >= T.size() || T[idx - 1] == -1) return true;if (!dfs(T, idx * 2, lastVal) || T[idx - 1] <= lastVal) return false;lastVal = T[idx - 1];return dfs(T, idx * 2 + 1, lastVal);
}bool isBST(vector<int>& T) {int lastVal = INT32_MIN;return dfs(T, 1, lastVal);
}

根据层序序列建立二叉树

题目描述

设一棵二叉树层序遍历序列存储于一个一维数组中,空结点用 INT32_MAX 表示,试编写算法建立该二叉树的二叉链表。

解题代码

TreeNode* createTreeByOrder(vector<int>& order) {if (order.front() == INT32_MAX) return nullptr;queue<TreeNode*> q;int idx = 0;TreeNode* root = new TreeNode(order[idx++]);q.emplace(root);while (!q.empty()) {TreeNode* fNode = q.front();q.pop();if (fNode == nullptr) continue;if (idx < order.size()) {TreeNode* lChild = nullptr;if (order[idx] != INT32_MAX) {lChild = new TreeNode(order[idx]);}fNode->left = lChild;q.emplace(lChild);++idx;}if (idx < order.size()) {TreeNode* rChild = nullptr;if (order[idx] != INT32_MAX) {rChild = new TreeNode(order[idx]);}fNode->right = rChild;q.emplace(rChild);++idx;}}return root;
}

相关文章:

王道数据结构编程题 二叉树

二叉树定义 以下为本文解题代码的二叉树定义。 struct TreeNode {int val;TreeNode* left, *right;TreeNode(int val 0, TreeNode* left nullptr, TreeNode* right nullptr): val(val), left(left), right(right) {} };非递归后序遍历 题目描述 编写后序遍历二叉树的非递…...

登录怎么实现的,密码加密了嘛?使用明文还是暗文,知道怎么加密嘛?

在Java中登录功能的实现通常包括以下步骤&#xff0c;其中密码应该以加密形式存储在数据库中&#xff0c;而不以明文形式存储&#xff0c;以增强安全性&#xff1a; 登录功能的实现步骤&#xff1a; 用户输入&#xff1a; 用户在登录页面上输入用户名和密码。 传输到服务器&a…...

Nginx和Tomcat负载均衡实现session共享

以前的项目使用Nginx作为反向代理实现了多个Tomcat的负载均衡&#xff0c;为了实现多个Tomcat之间的session共享&#xff0c;使用了开源的Memcached-Session-Manager框架。 此框架的优势&#xff1a; 1、支持Tomcat6和Tomcat7 2、操作粘性或不黏性Session 3、没有单点故障 4、T…...

【算法题】210. 课程表 II

题目&#xff1a; 现在你总共有 numCourses 门课需要选&#xff0c;记为 0 到 numCourses - 1。给你一个数组 prerequisites &#xff0c;其中 prerequisites[i] [ai, bi] &#xff0c;表示在选修课程 ai 前 必须 先选修 bi 。 例如&#xff0c;想要学习课程 0 &#xff0c;…...

“数据类型不一致”会走索引吗?

分析&回答 字符串类型的索引 id_1 varchar(20) NOT NULL这样下面两条语句的结果是一样的&#xff1a; SELECT * FROM ix_test WHERE id_11; SELECT * FROM ix_test WHERE id_11;执行计划是不同的&#xff1a; mysql> explain select * from ix_test where id_11; | 1 …...

Leetcode 1572.矩阵对角线元素之和

给你一个正方形矩阵 mat&#xff0c;请你返回矩阵对角线元素的和。 请你返回在矩阵主对角线上的元素和副对角线上且不在主对角线上元素的和。 示例 1&#xff1a; 输入&#xff1a;mat [[1,2,3],[4,5,6],[7,8,9]] 输出&#xff1a;25 解释&#xff1a;对角线的和为&#xff…...

[PG]将一行数据打散成多行数据

原始数据 比如有如此表结构定义: 假如查询数据如下&#xff1a; select dt as "日期",bj_count as "北京", sh_count as "上海",gz_count as "广州", sz_count as "深圳" from city_stats order by dt--------------------…...

二蛋赠书一期:《快捷学习Spring》

文章目录 前言活动规则参与方式本期赠书《快捷学习Spring》关于本书作者介绍内容简介读者对象 结语 前言 大家好&#xff01;我是二蛋&#xff0c;一个热爱技术、乐于分享的工程师。在过去的几年里&#xff0c;我一直通过各种渠道与大家分享技术知识和经验。我深知&#xff0c…...

Threejs汽车展厅

2023-09-06-16-29-40 预览&#xff1a;https://9kt8fy-1234.csb.app/ 源码链接...

LeetCode:207. 课程表、210. 课程表 II(拓扑排序 C++)

目录 207. 课程表 题目描述&#xff1a; 实现代码与解析&#xff1a; 拓扑排序 210. 课程表 II 题目描述&#xff1a; 实现代码与解析&#xff1a; 拓扑排序 原理思路&#xff1a; 207. 课程表 题目描述&#xff1a; 你这个学期必须选修 numCourses 门课程&#xff0…...

如何使用组件

可以复用的代码写到组件里面&#xff0c;比如左侧的导航栏 1.写好一个组件 记得结构写在template标签里面&#xff0c;当然div也可以 2.在需要使用的地方&#xff0c;用标签使用组件 3.在使用的文件内import此组件 import CommonAside from /components/CommonAside.vue; …...

Android 13.0 Launcher3定制之双层改单层(去掉抽屉式二)

1.概述 在13.0的系统产品开发中,对于在Launcher3中的抽屉模式也就是双层模式,在系统原生的Launcher3中就是双层抽屉模式的, 但是在通过抽屉上滑的模式拉出app列表页,但是在一些产品开发中,对于单层模式的Launcher3的产品模式也是常用的功能, 所以需要了解抽屉模式,然后修…...

对卷积的一点具象化理解

前言 卷积的公式一般被表示为下式&#xff1a; 对新手来说完全看不懂这是干什么&#xff0c;这个问题需要结合卷积的应用场景来说。 原理 卷积比较广泛的应用是在信号与系统中&#xff0c;所以有些公式的定义会按照信息流的习惯。假设存在一串信号g(x)经过一个响应h(x)时他的响…...

NV12数据格式转H265编码格式实现过程

一、需求 在视频处理和传输应用中&#xff0c;将视频数据编码为高效的格式是非常重要的。H.265&#xff08;也称为HEVC&#xff09;是一种先进的视频编码标准&#xff0c;具有更好的压缩性能和图像质量&#xff0c;相比于传统的编码标准&#xff08;如H.264&#xff09;&#…...

ubuntu 22.04 深度学习环境配置

第一步 安装驱动 网址&#xff1a;https://www.nvidia.com/download/index.aspx 根据硬件选择&#xff0c;我这里是 ubuntu 服务器,显卡是v100 sudo su root chmod ax NVIDIA //按 TAB 即可 加运行权限 # 禁用原显卡驱动 vim /etc/modprobe.d/blacklist.conf # 在最后一行…...

支付宝小程序集成mqtt兼容IOS和安卓

1. 前言 ​ 去年就想做支付宝小程序接入mqtt协议。但最终多方咨询&#xff0c;问客服问社区得到的答案都是支付宝小程序不能直接支持mqtt协议。偶然间发现徐宏大神的佳作&#xff0c;终于发现了xmqtt.js这个好东西。它实现了支付宝小程序完美接入mqtt协议&#xff0c;设备可以…...

在Qt5中SQLite3的使用

一、SQLite简要介绍 什么是SQLite SQLite是一个进程内的库&#xff0c;实现了自给自足的、无服务器的、零配置的、事务性的 SQL 数据库引擎。它是一个零配置的数据库&#xff0c;这意味着与其他数据库不一样&#xff0c;您不需要在系统中配置。 就像其他数据库&#xff0c;S…...

使用Docker部署debezium来监控 MySQL 数据库

使用Docker部署debezium来监控 MySQL 数据库 Debezium是一个分布式平台,它将来自现有数据库的信息转换为事件流,使应用程序能够检测并立即响应数据库中的行级更改。 Debezium构建在Apache Kafka之上,并提供了一组Kafka Connect兼容的连接器。每个连接器都与特定的数据库管…...

百度低质量站点怎么办?解决百度低质量站点的方法和工具

百度低质量站点怎么恢复&#xff1f;这是许多网站主和运营人员在SEO优化过程中经常面临的一个问题。百度作为中国最大的搜索引擎&#xff0c;对于网站收录和排名具有至关重要的影响。然而&#xff0c;由于各种原因&#xff0c;有些网站可能面临被百度降权或收录减少的情况。那么…...

MSOS604A是德科技keysight MSOS604A示波器

181/2461/8938Infiniium S系列示波器融合了创新技术&#xff0c;旨在提供卓越的测量。新的10位ADC和低噪声前端技术协同工作&#xff0c;提供高达8 GHz的性能和业界最佳的信号完整性。一个高级框架&#xff0c;配有可快速启动的固态硬盘、可轻松触摸的15英寸电容式显示屏和可快…...

Python爬虫实战:研究MechanicalSoup库相关技术

一、MechanicalSoup 库概述 1.1 库简介 MechanicalSoup 是一个 Python 库,专为自动化交互网站而设计。它结合了 requests 的 HTTP 请求能力和 BeautifulSoup 的 HTML 解析能力,提供了直观的 API,让我们可以像人类用户一样浏览网页、填写表单和提交请求。 1.2 主要功能特点…...

云启出海,智联未来|阿里云网络「企业出海」系列客户沙龙上海站圆满落地

借阿里云中企出海大会的东风&#xff0c;以**「云启出海&#xff0c;智联未来&#xff5c;打造安全可靠的出海云网络引擎」为主题的阿里云企业出海客户沙龙云网络&安全专场于5.28日下午在上海顺利举办&#xff0c;现场吸引了来自携程、小红书、米哈游、哔哩哔哩、波克城市、…...

学校时钟系统,标准考场时钟系统,AI亮相2025高考,赛思时钟系统为教育公平筑起“精准防线”

2025年#高考 将在近日拉开帷幕&#xff0c;#AI 监考一度冲上热搜。当AI深度融入高考&#xff0c;#时间同步 不再是辅助功能&#xff0c;而是决定AI监考系统成败的“生命线”。 AI亮相2025高考&#xff0c;40种异常行为0.5秒精准识别 2025年高考即将拉开帷幕&#xff0c;江西、…...

安宝特方案丨船舶智造的“AR+AI+作业标准化管理解决方案”(装配)

船舶制造装配管理现状&#xff1a;装配工作依赖人工经验&#xff0c;装配工人凭借长期实践积累的操作技巧完成零部件组装。企业通常制定了装配作业指导书&#xff0c;但在实际执行中&#xff0c;工人对指导书的理解和遵循程度参差不齐。 船舶装配过程中的挑战与需求 挑战 (1…...

Kafka入门-生产者

生产者 生产者发送流程&#xff1a; 延迟时间为0ms时&#xff0c;也就意味着每当有数据就会直接发送 异步发送API 异步发送和同步发送的不同在于&#xff1a;异步发送不需要等待结果&#xff0c;同步发送必须等待结果才能进行下一步发送。 普通异步发送 首先导入所需的k…...

「全栈技术解析」推客小程序系统开发:从架构设计到裂变增长的完整解决方案

在移动互联网营销竞争白热化的当下&#xff0c;推客小程序系统凭借其裂变传播、精准营销等特性&#xff0c;成为企业抢占市场的利器。本文将深度解析推客小程序系统开发的核心技术与实现路径&#xff0c;助力开发者打造具有市场竞争力的营销工具。​ 一、系统核心功能架构&…...

CVPR2025重磅突破:AnomalyAny框架实现单样本生成逼真异常数据,破解视觉检测瓶颈!

本文介绍了一种名为AnomalyAny的创新框架&#xff0c;该方法利用Stable Diffusion的强大生成能力&#xff0c;仅需单个正常样本和文本描述&#xff0c;即可生成逼真且多样化的异常样本&#xff0c;有效解决了视觉异常检测中异常样本稀缺的难题&#xff0c;为工业质检、医疗影像…...

Kubernetes 节点自动伸缩(Cluster Autoscaler)原理与实践

在 Kubernetes 集群中&#xff0c;如何在保障应用高可用的同时有效地管理资源&#xff0c;一直是运维人员和开发者关注的重点。随着微服务架构的普及&#xff0c;集群内各个服务的负载波动日趋明显&#xff0c;传统的手动扩缩容方式已无法满足实时性和弹性需求。 Cluster Auto…...

C++_哈希表

本篇文章是对C学习的哈希表部分的学习分享 相信一定会对你有所帮助~ 那咱们废话不多说&#xff0c;直接开始吧&#xff01; 一、基础概念 1. 哈希核心思想&#xff1a; 哈希函数的作用&#xff1a;通过此函数建立一个Key与存储位置之间的映射关系。理想目标&#xff1a;实现…...

数据库——redis

一、Redis 介绍 1. 概述 Redis&#xff08;Remote Dictionary Server&#xff09;是一个开源的、高性能的内存键值数据库系统&#xff0c;具有以下核心特点&#xff1a; 内存存储架构&#xff1a;数据主要存储在内存中&#xff0c;提供微秒级的读写响应 多数据结构支持&…...