常见算法有:

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++实现的更多相关文章

  1. python常用算法(5)——树,二叉树与AVL树

    1,树 树是一种非常重要的非线性数据结构,直观的看,它是数据元素(在树中称为节点)按分支关系组织起来的结构,很像自然界中树那样.树结构在客观世界中广泛存在,如人类社会的族谱和各种社会组织机构都可用树形 ...

  2. (2)Java数据结构--二叉树 -和排序算法实现

    === 注释:此人博客对很多个数据结构类都有讲解-并加以实例 Java API —— ArrayList类 & Vector类 & LinkList类Java API —— BigDe ...

  3. Leetcode——二叉树常考算法整理

    二叉树常考算法整理 希望通过写下来自己学习历程的方式帮助自己加深对知识的理解,也帮助其他人更好地学习,少走弯路.也欢迎大家来给我的Github的Leetcode算法项目点star呀~~ 二叉树常考算法 ...

  4. ACM常用算法及练习(2)

    ACM常用算法及练习 知识类型 重要度 容易度 应掌握度 典型题 其他           数据结构(5) 链表 ★★☆ ★★★ ★★☆     栈 stack ★★★ ★★★ ★★★ HLoj120 ...

  5. ACM常用算法及练习(1)

    ACM常用算法及练习 第一阶段:练经典常用算法,下面的每个算法给我打上十到二十遍,同时自己精简代码,因为太常用,所以要练到写时不用想,10-15分钟内打完,甚至关掉显示器都可以把程序打出来. 1.最短 ...

  6. Python之路,Day21 - 常用算法学习

    Python之路,Day21 - 常用算法学习   本节内容 算法定义 时间复杂度 空间复杂度 常用算法实例 1.算法定义 算法(Algorithm)是指解题方案的准确而完整的描述,是一系列解决问题的 ...

  7. python 常用算法学习(2)

    一,算法定义 算法(Algorithm)是指解题方案的准确而完整的描述,是一系列解决问题的清晰指令,算法代表着用系统的方法描述解决问题的策略机制.也就是说,能够对一定规范的输入,在有限时间内获得所要求 ...

  8. 剑指Offer——知识点储备-常用算法

    剑指Offer--知识点储备-常用算法 快速排序 注:若排序是有序的,采用快排,则退化为冒泡排序. 解决这个问题,采用两个选取基准的方法 (1)随机选取基数(在这个区间内随机取一个数) 出现的恶劣情况 ...

  9. Python常用算法

    本节内容 算法定义 时间复杂度 空间复杂度 常用算法实例 1.算法定义 算法(Algorithm)是指解题方案的准确而完整的描述,是一系列解决问题的清晰指令,算法代表着用系统的方法描述解决问题的策略机 ...

  10. 总结Objective-c常用算法

          今天是星期天,想睡到10点起床,结果认为自己太奢侈了,不能这么做,于是把闹钟设置成了6:30:结果终于9:36醒了,起床,无缘无故迟了,好吧,就算太累了吧,周天就原谅自己一回.终于到了中午 ...

随机推荐

  1. flex 布局 实现三点筛子

    实现麻将中三点筛子:效果如下图 具体实现代码: html代码: <div class="box"> <div class="item"> ...

  2. Openstack组建部署 — Environment of Controller Node

    目录 目录 前文列表 Controller Node Install and configure components Setup DNS Server Setup NTP Server Instal ...

  3. PHP面试 MySQL查询优化

    MySQL查询优化 面试题一 请简述项目中优化SQL语句执行效率的方法,从那些方面,SQL语句性能如何分析? 优化查询过程中的数据访问.优化长难的查询语句.优化特定类型的查询语句 分析SQL语句方法 ...

  4. Nginx网络架构实战学习笔记(五):大访问量优化整体思路、ab压力测试及nginx性能统计模块、nginx单机1w并发优化

    文章目录 大访问量优化整体思路 ab压力测试及nginx性能统计模块 ab压力测试及nginx性能统计模块 ab压力测试 nginx性能统计模块 nginx单机1w并发优化 整装待发: socket ...

  5. 洛谷 P1742 最小圆覆盖 (随机增量)

    题目链接:P1742 最小圆覆盖 题意 给出 N 个点,求最小的包含所有点的圆. 思路 随机增量 最小圆覆盖一般有两种做法:随机增量和模拟退火.随机增量的精确度更高,这里介绍随机增量的做法. 先将所有 ...

  6. python *arg和**kwargs的区别

    转载自:https://www.cnblogs.com/yunguoxiaoqiao/p/7626992.html 一.*args的使用方法 *args 用来将参数打包成tuple给函数体调用 举个栗 ...

  7. JDK动态代理源码剖析

    关键代码: 1.Proxy.newInstance: private static final Class<?>[] constructorParams = { InvocationHan ...

  8. ubuntu中搭建基本的开发环境

    1.搭建基本开发环境: sudo apt-get install build-essential 2.安装语法.词法分析器 sudo apt-get install bison flex 3.安装C函 ...

  9. 《node.js开发指南》partial is not defined的解决方案

    由于ejs的升级,<node.js开发指南>中使用的 partial 函数已经摒弃,使用foreach,include代替 原来的代码是: <%- partial('listitem ...

  10. MyEclipse中android 项目如何解决第三方jar无法关联源码的问题( The JAR of this class file belongs to container 'Android Private Libraries' which does not allow modifications to source attachments on its entries.)

    若我们要为第三方jar(android-support-v4.jar)关联源码通常的做法是 右键项目 单击菜单Properties 单击菜单 Java Build Path 单击 Libraries ...