【二叉树】二叉树常用算法的C++实现
常见算法有:
1.求二叉树的最大深度
2.求二叉树的最小深度
3.二叉树的层次遍历
4.二叉树的前序遍历
5.二叉树的中序遍历
6.二叉树的后序遍历
7.求二叉树的节点个数
8.求二叉树的叶节点个数
9.判断二叉树是否为平衡二叉树
10.判断二叉树是否为满二叉树
11.判断两个二叉树是否完全相同
12.判断二叉树是否为二叉搜索树
13.将有序数组转换为二叉搜索树
14.镜像翻转二叉树
15.二叉树的“之”字形遍历
16.判断两个二叉树是否互为镜像
17.判断一个二叉树本身是否为镜像二叉树(对称二叉树)
18.求两个节点最近的公共祖先
19.判断两个节点是否为堂兄弟(深度相同且父节点不同)
(涉及到的相关概念不再累述)
0.二叉树结构体定义
struct TreeNode{
int val;
TreeNode* left;
TreeNode* right;
TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
1.求二叉树的最大深度
int maxDepth(TreeNode* root){
if (root == NULL) return ;
int left = maxDepth(root->left);
int right = maxDepth(root->right);
return max(left, right) + ;
}
2.求二叉树的最小深度
int minDepth(TreeNode* root){
if (root == NULL) return ;
return getMin(root);
}
int getMin(TreeNode* root){
if (root == NULL) return INT_MAX;
if (root->left == NULL && root->right == NULL) return ;
return min(getMin(root->left), getMin(root->right)) + ;
}
3.二叉树的层次遍历
void levelView(TreeNode* root){
vector<int> s;
queue<TreeNode*> p, q;
p.push(root);
q = p;
while (!p.empty()){
p = queue<TreeNode*>();
s.clear();
while (!q.empty()){
TreeNode* tmp = q.front();
q.pop();
s.push_back(tmp->val);
if (tmp->left != NULL) p.push(tmp->left);
if (tmp->right != NULL) p.push(tmp->right);
}
for (auto i : s) cout << i << " ";
cout << endl;
q = p;
}
}
4.二叉树的前序遍历
void preView(TreeNode* root){
if (root != NULL){
cout << root->val << " ";
preView(root->left);
preView(root->right);
}
}
5.二叉树的中序遍历
void midView(TreeNode* root){
if (root != NULL){
midView(root->left);
cout << root->val << " ";
midView(root->right);
}
}
6.二叉树的后序遍历
void postView(TreeNode* root){
if (root != NULL){
postView(root->left);
postView(root->right);
cout << root->val << " ";
}
}
7.求二叉树的节点个数
int nodeNumbers(TreeNode* root){
if (root == NULL) return ;
int left = nodeNumbers(root->left);
int right = nodeNumbers(root->right);
return left + right + ;
}
8.求二叉树的叶节点个数
int leafNodeNumbers(TreeNode* root){
if (root == NULL) return ;
if (root->left == NULL && root->right == NULL) return ;
return leafNodeNumbers(root->left) + leafNodeNumbers(root->right);
}
9.判断二叉树是否为平衡二叉树
int countFloor(TreeNode* root){//计算层数
if (!root) return ;
return + max(countFloor(root->left), countFloor(root->right));
}
bool isBalanced(TreeNode* root) {
if (!root) return true;
if (abs(countFloor(root->left) - countFloor(root->right)) > ) return false;
else return isBalanced(root->left) && isBalanced(root->right);
}
10.判断二叉树是否为满二叉树
bool isFullTree(TreeNode* root){
if (root == NULL) return true;
int n = nodeNumbers(root) + ;//满二叉树节点数为2^n-1,利用算法7求节点数
while (n > ){
if (n % == ) return false;
n /= ;
}
return true;
}
11.判断两个树是否完全相同
bool isSameTree(TreeNode* p, TreeNode* q) {
if (!p && !q) return true;
if (q != NULL && p != NULL){
if (q->val != p->val) return false;
else return isSameTree(p->left, q->left) && isSameTree(p->right, q->right);
} else
return false;
}
12.判断二叉树是否为二叉搜索树
void midView(TreeNode* p, vector<int> &s){
if (p){
midView(p->left, s);
s.push_back(p->val);
midView(p->right, s);
}
}
bool isValidBST(TreeNode* root) {
vector<int> s;
midView(root, s);
if (s.size() < ) return true;
for (int i = ; i < s.size() - ; i++){
if (s[i] >= s[i + ]) return false;
}
return true;
}
13.将有序数组转换为二叉搜索树
TreeNode* buildTree(vector<int> &num, int left, int right) {
if (left > right) return NULL;
int mid = (left + right) / ;
TreeNode* cur = new TreeNode(num[mid]);
cur->left = buildTree(num, left, mid - );
cur->right = buildTree(num, mid + , right);
return cur;
}
TreeNode* sortedArrayToBST(vector<int>& nums) {
return buildTree(nums, , nums.size() - );
}
14.镜像翻转二叉树
TreeNode* invertTree(TreeNode* root) {
if (root != NULL){
TreeNode *tmp = root->left;
root->left = root->right;
root->right = tmp;
invertTree(root->left);
invertTree(root->right);
}
return root;
}
15.二叉树之字形遍历(第一层从左往右遍历,第二层从右往左遍历,第三次从左往右…)
vector<vector<int> > zigzagLevelOrder(TreeNode* root) {
vector<vector<int> > s;
bool change = false;
if (root == NULL) return s;
queue<TreeNode*> p;
p.push(root);
vector<int> t;
queue<TreeNode*> q = p;
t.push_back(root->val);
while (!q.empty()){
q = queue<TreeNode*>();
t.clear();
while (!p.empty()){
TreeNode* tmp = p.front();
t.push_back(tmp->val);
p.pop();
if (tmp->left != NULL) q.push(tmp->left);
if (tmp->right != NULL) q.push(tmp->right);
}
p = q;
if (change){
change = false;
reverse(t.begin(), t.end());
} else change = true;
s.push_back(t);
}
return s;
}
16.判断两个二叉树是否互为镜像
bool isMirror(TreeNode* p, TreeNode* q){
if (p == NULL && q == NULL) return true;
if (p == NULL || q == NULL) return false;
if (p->val != q->val) return false;
return isMirror(p->left, q->right) && isMirror(p->right, q->left);
}
17.判断二叉树本身是否为镜像二叉树
bool isMirrorTree(TreeNode* root){
return isMirror(root, root);//利用算法16,如果一个树是镜像的,那么它和自己本身互为镜像
}
18.求二叉树中两个节点的最近公共祖先
void help(TreeNode* p, map<TreeNode*, TreeNode*> &q){
if (p){
if (p->left) q[p->left] = p;
if (p->right) q[p->right] = p;
help(p->left, q);
help(p->right, q);
}
}
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
map<TreeNode*, TreeNode*> m;
TreeNode* head = root;
help(root, m);
if (m[p] == q) return q;
if (m[q] == p) return p;
while (p != head){
TreeNode* tmp = q;
while (tmp != head){
if (p == tmp || m[tmp] == p) return p;
if (m[p] == tmp) return tmp;
tmp = m[tmp];
}
p = m[p];
}
return head;
}
19.判断二叉树中两个节点是否为堂兄弟(深度相同但父节点不同)
void help(TreeNode *root, map<int, int> &p){
if (root != NULL){
if (root->left != NULL) p[root->left->val] = root->val;
if (root->right != NULL) p[root->right->val] = root->val;
help(root->left, p);
help(root->right, p);
}
}
map<int, int> p;
bool isCousins(TreeNode* root, int x, int y) {
help(root, p);
if (p[x] == || p[y] == ) return false;
if (p[x] == p[y]) return false;
int xi = , yi = ;
while (p[x] != p[y]){
if (p[p[x]] != ){
x = p[x];
xi++;
}
if (p[p[y]] != ){
y = p[y];
yi++;
}
}
return xi == yi;
}
【二叉树】二叉树常用算法的C++实现的更多相关文章
- python常用算法(5)——树,二叉树与AVL树
1,树 树是一种非常重要的非线性数据结构,直观的看,它是数据元素(在树中称为节点)按分支关系组织起来的结构,很像自然界中树那样.树结构在客观世界中广泛存在,如人类社会的族谱和各种社会组织机构都可用树形 ...
- (2)Java数据结构--二叉树 -和排序算法实现
=== 注释:此人博客对很多个数据结构类都有讲解-并加以实例 Java API —— ArrayList类 & Vector类 & LinkList类Java API —— BigDe ...
- Leetcode——二叉树常考算法整理
二叉树常考算法整理 希望通过写下来自己学习历程的方式帮助自己加深对知识的理解,也帮助其他人更好地学习,少走弯路.也欢迎大家来给我的Github的Leetcode算法项目点star呀~~ 二叉树常考算法 ...
- ACM常用算法及练习(2)
ACM常用算法及练习 知识类型 重要度 容易度 应掌握度 典型题 其他 数据结构(5) 链表 ★★☆ ★★★ ★★☆ 栈 stack ★★★ ★★★ ★★★ HLoj120 ...
- ACM常用算法及练习(1)
ACM常用算法及练习 第一阶段:练经典常用算法,下面的每个算法给我打上十到二十遍,同时自己精简代码,因为太常用,所以要练到写时不用想,10-15分钟内打完,甚至关掉显示器都可以把程序打出来. 1.最短 ...
- Python之路,Day21 - 常用算法学习
Python之路,Day21 - 常用算法学习 本节内容 算法定义 时间复杂度 空间复杂度 常用算法实例 1.算法定义 算法(Algorithm)是指解题方案的准确而完整的描述,是一系列解决问题的 ...
- python 常用算法学习(2)
一,算法定义 算法(Algorithm)是指解题方案的准确而完整的描述,是一系列解决问题的清晰指令,算法代表着用系统的方法描述解决问题的策略机制.也就是说,能够对一定规范的输入,在有限时间内获得所要求 ...
- 剑指Offer——知识点储备-常用算法
剑指Offer--知识点储备-常用算法 快速排序 注:若排序是有序的,采用快排,则退化为冒泡排序. 解决这个问题,采用两个选取基准的方法 (1)随机选取基数(在这个区间内随机取一个数) 出现的恶劣情况 ...
- Python常用算法
本节内容 算法定义 时间复杂度 空间复杂度 常用算法实例 1.算法定义 算法(Algorithm)是指解题方案的准确而完整的描述,是一系列解决问题的清晰指令,算法代表着用系统的方法描述解决问题的策略机 ...
- 总结Objective-c常用算法
今天是星期天,想睡到10点起床,结果认为自己太奢侈了,不能这么做,于是把闹钟设置成了6:30:结果终于9:36醒了,起床,无缘无故迟了,好吧,就算太累了吧,周天就原谅自己一回.终于到了中午 ...
随机推荐
- js判断变量未定义
js判断变量未定义 控制台输出未定义变量a会报错: 我们打印出a的数据类型是: 我们可以看到未定义变量的数据类型是 "undefined" 所以判断js变量是否未定义的方法就是 t ...
- spring boot starter开发
作为公司的技术保障部,一直承担着技术方向的把控,最近公司准备全面转入spring boot的开发.所以我们部门也一直在调研相关的技术知识点: 使用springboot开发应用已经有一段时间了,我们都沉 ...
- poi提取docx中的文字和图片
package com.fry.poiDemo.dao; import java.io.File; import java.io.FileInputStream; import java.io.Fil ...
- Mysql任意读取客户端文件复现
本机执行 python rogue_mysql_server.py 目标机器上连接本机数据库 mysql -u root -p -h 本机IP mysql -h 192.168.250.132 -ur ...
- 在mac版virtual box中安装ubuntu虚拟机的NAT/Host-Only网络配置踩坑记录
之前用惯了vmware和parallels desktop,网络配置十分智能,基本不用自己配置.由于版权原因,工作电脑上换了免费的virtual box用,四五年都完全在虚拟机里干活的本菜鸡居然在虚拟 ...
- Set 对象和WeakSet对象
Set对象是值的集合,你可以按照插入的顺序迭代它的元素. Set中的元素只会出现一次,即 Set 中的元素是唯一的,一种有效去重方式. , , , , ]); console.log(set1.has ...
- 树莓派上Opencv highgui的问题
错误描述:https://bbs.csdn.net/topics/394616975?page=1#post-409508178 解决方案:直接改系统环境变量 # vim /etc/profile e ...
- LeetCode Array Easy 26.Remove Duplicates from Sorted Array 解答及疑惑
Description Given a sorted array nums, remove the duplicates in-place such that each element appear ...
- linux网络配置 转
1.常用配置网络指令 (1) 配置eth0的IP地址, 同时激活该设备 1 sudo ifconfig eth0 192.168.1.10 netmask 255.255.255.0 up (2) 添 ...
- CSV模块的使用
1.csv简介 CSV (Comma Separated Values),即逗号分隔值(也称字符分隔值,因为分隔符可以不是逗号),是一种常用的文本 格式,用以存储表格数据,包括数字或者字符.很多程序在 ...