文章目录

  • 一、二叉树的层次遍历
    • 1、题目描述——LeetCode.102
    • 2、分析
    • 3、实现
  • 二、二叉树(Binary Tree)
    • 1、相关概念
      • 二叉树
      • 满二叉树
      • 完全二叉树
      • 区分
    • 2、二叉树的表示(存储)
      • (1)链式存储法
      • (2)顺序存储法
      • (3)分析
    • 3、二叉树遍历
      • (1)方法
      • (2)实现

二叉树是最常用的树结构

一、二叉树的层次遍历

1、题目描述——LeetCode.102

给定一个二叉树,返回其按层次遍历的节点值。 (即逐层地,从左到右访问所有节点)。

给定二叉树: [3,9,20,null,null,15,7],

返回其层次遍历结果:

2、分析

  • 从输出的结果来看,将根节点到叶子节点每层作为一个向量的二维向量中;
  • 一般的遍历:将节点存储在队列中,每次从队首输出一个节点并将其左右子节点插入到队列中。
  • 此题需要标记每层个数从而可以区分具体是哪层的节点==》nowcount、nextcount

3、实现

/*** Definition for a binary tree node.* struct TreeNode {*     int val;*     TreeNode *left;*     TreeNode *right;*     TreeNode(int x) : val(x), left(NULL), right(NULL) {}* };*/
class Solution {public:vector<vector<int>> levelOrder(TreeNode* root) {// 定义二维向量,存储结果vector<vector<int>> res;if(root == NULL)return res;// 定义队列 my_queue,存储需要访问的节点queue<TreeNode*> my_queue;my_queue.push(root);TreeNode *temp;vector<int> lev;lev.push_back(root->val);res.push_back(lev);// nowcount 用于标记本层还有几个未遍历的节点// nextcount 用于标记下一层的节点的个数int nowcount = 1, nextcount = 0;while(!my_queue.empty()){vector<int> lev;while(nowcount > 0){temp = my_queue.front();if(temp->left != NULL){my_queue.push(temp->left);nextcount++;lev.push_back(temp->left->val);}if(temp->right != NULL){my_queue.push(temp->right);nextcount++;lev.push_back(temp->right->val);}my_queue.pop();nowcount--;}if(!lev.empty())res.push_back(lev);nowcount = nextcount;nextcount = 0;}return res;}
};

二、二叉树(Binary Tree)

1、相关概念

二叉树

每个节点最多有两个子节点(左子结点、右子节点)。

满二叉树

叶子节点全都在最底层,除叶子节点外,每个结点都有左右两个子节点。

完全二叉树

叶子节点都在最底下两层,最后一层的叶子节点都靠左排列,并且除了最后一层,其他层的节点个数都要达到最大。

区分

2、二叉树的表示(存储)

两种存储方法:
①基于指针或引用的二叉链式存储法——常用
②基于数组的顺序存储方法

(1)链式存储法

每个节点有三个字段,分别存储:数据、指向左右子节点的指针。
==》只要通过根节点,就可以通过左右节点的指针,将整棵树串起来。

(2)顺序存储法

一般情况下,为了方便计算子节点,根节点会存储在下标为 1 的位置。

  • 将根节点存储在下标 i = 1 的位置,其左节点存储在下标 2 * i = 2 的位置,右子节点存储在 2 * i + 1 = 3的位置。
  • 依次类推:
    • 若结点 X 存储在数组中下标为 i 的位置,
    • 其左节点下标: 2 * i
    • 其右节点下标: 2 * i + 1
    • 其父节点下标:i / 2

(3)分析

若二叉树为完全二叉树,则数组存储是最节省内存的一种方式(不需要存储额外的左右子节点的指针)

3、二叉树遍历

(1)方法

三种方法:前序遍历、中序遍历、后序遍历
==》节点与它的左右子树节点遍历的先后顺序:中代表该节点,左代表其左子树,右代表其右子树。

  • 前序遍历:中、左、右
  • 中序遍历:左、中、右
  • 后序遍历:左、右、中

  • 前序遍历:abdefgc
  • 中序遍历:debgfac
  • 后序遍历:edgfbca

(2)实现

#include<iostream>
#include<string>
#include<stack>
#include<vector>
#include<queue>
using namespace std;class BiNode{public:char data;BiNode *lchild,*rchild;
};// 对于二叉树来说,只需要存放指向树根节点的指针
class BiTree{private:BiNode * root;int height;void pre_Order(BiNode *t);void in_Order(BiNode *t);void post_Order(BiNode *t);BiNode * create(string &s, int &ops);void get_Height(BiNode *t, int h);
public:BiTree(){root = NULL;height = 0;}// 按照前序遍历序列创建二叉树void createBiTree(string s);// 前序遍历二叉树void preOrder();// 中序遍历二叉树void inOrder();// 后序遍历二叉树(递归方法)void postOrder();// 后序遍历二叉树(使用栈的非递归方法)void postOrder1();// 层序遍历二叉树void levelOrder();// 二叉树的高度int getHeight();// 求两个节点的最大公共祖先void ancestor(char A, char B);
};// 递归创建二叉树,如果是#表示空节点
// 应用字符串s创建二叉树
BiNode * BiTree::create(string &s, int &pos)
{++pos;BiNode *t;if((unsigned)pos >= s.size())return NULL;else{if(s[pos] == '#')t = NULL;else{t = new BiNode;t->data = s[pos];t->lchild = create(s, pos);t->rchild = create(s, pos);}return t;}
}// 按照前序遍历序列创建二叉树
void BiTree::createBiTree(string s){int pos = -1;root = create(s, pos);
}// 前序遍历二叉树
void BiTree::preOrder(){pre_Order(root);cout<<endl;
}
void BiTree::pre_Order(BiNode *t){if(t != NULL){cout<<t->data<<" ";pre_Order(t->lchild);pre_Order(t->rchild);}
}// 中序遍历二叉树
void BiTree::inOrder(){in_Order(root);cout<<endl;
}
void BiTree::in_Order(BiNode *t){if(t != NULL){in_Order(t->lchild);cout<<t->data<<" ";in_Order(t->rchild);}
}// 后序遍历二叉树(递归方法)
void BiTree::postOrder()
{post_Order(root);cout<<endl;
}
void BiTree::post_Order(BiNode *t){if(t != NULL){post_Order(t->lchild);post_Order(t->rchild);cout<<t->data<<" ";}
}// 后序遍历二叉树(使用栈的非递归方法)
// 用r记录右子树是否遍历,若没有遍历,则遍历右子树
void BiTree::postOrder1(){// p表示当前树节点指针// r表示最近访问的树节点指针BiNode *p, *r;r = NULL;p = root;stack<BiNode*> my_stack;while(p!=NULL || !my_stack.empty()){if(p){// 一直走到树的最左边my_stack.push(p);p = p->lchild;}else{p = my_stack.top();// 如果右子树没有遍历,遍历右子树if(p->rchild != NULL && p->rchild != r){p = p->rchild;my_stack.push(p);// 需要向左转,否则将会遍历右子树节点两边p = p->lchild;}// 否则遍历根节点else{p = my_stack.top();my_stack.pop();cout<<p->data<<" ";// 更新最近遍历的节点r = p;// 将遍历后的节点设为NULL,进行下一个节点的遍历p = NULL;}}}cout<<endl;
}// 使用队列进行层序遍历二叉树
void BiTree::levelOrder()
{if(root == NULL)return;queue<BiNode*> my_queue;my_queue.push(root);while(!my_queue.empty()){BiNode *t;t = my_queue.front();my_queue.pop();cout<<t->data<<" ";if(t->lchild != NULL)my_queue.push(t->lchild);if(t->rchild != NULL)my_queue.push(t->rchild);}cout<<endl;
}int BiTree::getHeight()
{get_Height(root,0);return height;
}
void BiTree::get_Height(BiNode *t, int h)
{if(t != NULL){++h;if(h > height)height = h;get_Height(t->lchild, h);get_Height(t->rchild, h);}
}int main(int argc, char const *argv[])
{BiTree a;string s;s = "ABD##E#F##C##";a.createBiTree(s);cout<<"前序遍历: "<<endl;a.preOrder();cout<<"中序遍历: "<<endl;a.inOrder();cout<<"后序遍历1: "<<endl;a.postOrder();cout<<"后序遍历2: "<<endl;a.postOrder1();cout<<"层序遍历: "<<endl;a.levelOrder();cout<<"树高:";cout<<a.getHeight()<<endl;return 0;
}

【编程3】二叉树遍历(LeetCode.102)相关推荐

  1. LeetCode 1379. 找出克隆二叉树中的相同节点(二叉树遍历)

    1. 题目 给你两棵二叉树,原始树 original 和克隆树 cloned,以及一个位于原始树 original 中的目标节点 target. 其中,克隆树 cloned 是原始树 original ...

  2. [二叉树遍历|BST]leetcode 538 把二叉搜索树转换为累加树

    [二叉树遍历|BST]leetcode 538 把二叉搜索树转换为累加树 1.题目 题目链接 给定一个二叉搜索树(Binary Search Tree),把它转换成为累加树(Greater Tree) ...

  3. leetcode 102 C++AC

    leetcode 102 我模仿二叉树的层序遍历的方法,自己写了一个.中间报错了,还特别去看了下这个文章https://blog.csdn.net/weixin_45799835/article/de ...

  4. java二叉树原理_史上最全二叉树遍历详解(Java实现,原理相同)

    二叉树遍历方法合集: 最近在LeetCode力扣上刷数据结构的二叉树合集,遇到的二叉树遍历方法,于是想理解透彻.本文讲解了二叉树遍历的四种方法,前.中.后序遍历. 对应题目: 94.二叉树的中序遍历 ...

  5. 【关于封装的那些事】 缺失封装 【关于封装的那些事】 泄露的封装 【关于封装的那些事】 不充分的封装 【图解数据结构】二叉查找树 【图解数据结构】 二叉树遍历...

    [关于封装的那些事] 缺失封装 目录 - 缺失封装 为什么不能缺失封装? 缺失封装潜在的原因 未意识到关注点会不断变化 混合关注点 幼稚的设计决策 示例分析一 示例分析二 总结 缺失封装 没有将实现变 ...

  6. l2-004 这是二叉搜索树吗?_LeetCode 例题精讲 | 11 二叉树转化为链表:二叉树遍历中的相邻结点...

    本期例题: LeetCode 98. Validate Binary Search Tree 验证二叉搜索树(Medium) LeetCode 426. Convert Binary Tree to ...

  7. 十八、二叉树遍历序列还原

    十八.二叉树遍历序列还原 文章目录 十八.二叉树遍历序列还原 题目描述 解题思路 上机代码 题目描述 给出二叉树的中序遍历序列和后序遍历序列,编程还原该二叉树. 输入: ​第1行为二叉树的中序遍历序列 ...

  8. leetcode 打印_剑指 Offer 32 - III 从上到下打印二叉树 III - leetcode 剑指offer

    题目难度: 中等 原题链接 今天继续更新剑指 offer 系列, 这道题相比昨天那道题多了个每层打印方向不同的需求, 聪明的你想到应该如何实现了吗? 老样子晚上 6 点 45 分准时更新公众号 每日精 ...

  9. 8606 二叉树遍历的建设和运营

    8606 二叉树遍历的建设和运营 时限:1000MS  内存限制:1000K 问题: 编程题   语言: 无限 叙述性说明 用二进制表示的名单二叉树结构:按第一个二进制序列,以便输入节点值(一个字符) ...

最新文章

  1. TimeUnit 使用
  2. 实战SSM_O2O商铺_37【商品】商品列表之View层的实现
  3. 【数据科学】 推荐一个更高效的数据清洗方法,建议收藏
  4. java 添加一个线程、创建响应的用户界面 。 演示示例代码
  5. 微软相关的开发资源列表(update)
  6. 关于Java的Object.clone()方法与对象的深浅拷贝,java面试题,java初级笔试题
  7. (计算机显示器主屏幕区域)桌面造句,部编版《语文园地四》教学反思模板(11页)-原创力文档...
  8. Reflect Refract (以水渲染为例)
  9. viper12a电源电路图_viper12a引脚功能图与引脚电压
  10. 【MDT】iPhone XS 系列屏幕素质报告
  11. 作为一名程序员,我都收集了哪些好玩的生成器?
  12. 《Java程序员,上班那点事儿》荣登北京新华书店销售榜第2名,立贴纪念!
  13. 随便写的:新戏剧之王,一部广义上的烂片观后感
  14. 无任何编程基础的人,该怎么入门编程?
  15. 自动写作ai-自动写作神器
  16. 水果之王之猕猴桃-系列三(猕猴桃的功能和禁忌)
  17. AI大模型加持,生成式搜索来了!
  18. Multimedia Event Extraction From News With a Unified Contrastive Learning Framework论文解读
  19. [apidoc]Apidoc-文档生成工具
  20. Oracle ERP财务系统——固定资产

热门文章

  1. qfile 计算文件有多少行_肉牛不喂精料行吗?如何计算肉牛一天喂多少精料?
  2. 虚拟计算机配置文件,如何更改虚拟内存位(可以解决由于启动计算机时出现了页面文件配置问题……).docx...
  3. 取值方法_我国细骨料试验方法标准分析及修订建议
  4. 进程用户态 上下文切换需要保存哪些_漫话性能:CPU上下文切换
  5. re正则表达式的使用
  6. 麒麟操作系统配置网络_讲解银河麒麟桌面操作系统
  7. mysql1067默认参数错误_MySQL 1067错误解决方法集合
  8. qt 中转化图片格式与大小的方法
  9. 【存储知识学习】第三章磁盘原理与技术3.2磁盘的通俗演绎和3.3磁盘相关高层技术--《大话存储》阅读笔记
  10. 【中间件】大数据之分布式消息队列Kafka