二叉树

一、二叉树理论基础

1.满二叉树:如果一棵二叉树只有度为0的结点和度为2的结点,并且度为0的结点在同一层上,则这棵二叉树为满二叉树。通俗话理解:从底层开始到顶部的所有节点都全部填满的二叉树。深度为k,则有2^k-1个节点

2.完全二叉树:除了最底层节点没有节满,其余每层节点都达到最大值,并且最底层节点全都从最左边开始,按照顺序节若干个节点,中间不能出现空缺部分。

3.搜索二叉树:是一个有序树,遵循左节点小于根节点、右节点大于根节点的原则依次从上到下排列展开。

4.平衡搜索二叉树:是指满足左子树与右子树的高度差不超过1要求的搜索二叉树。

二、二叉树的定义与遍历

1.遍历方法:前序(根左右)、中序(左根右)、后序(左右根);

2.二叉树可用链表和数组定义,链表定义符合深度搜索法,数组定义按照层级搜索(根节点位置为i,则其左右节点位置分别为2i+1,2i+2)。

3.二叉树链表定义:

 struct treeNode{
  int val;//数值
  treeNode* left;//左指针
  treeNode* right;//右指针
  treeNode(int x): val(x),left(NULL),right(NULL) {} // 构造函数

三、二叉树递归遍历

递归三步曲:

1.递归函数的参数和返回值

 void traversal(TreeNode* cur, vector<int>& vec) //vec用于存放节点数值

2.确定终止条件:当遍历节点为空时,就return

 if (cur == NULL) return;

3.单层递归逻辑

 //前序遍历
 vec.push_back(cur->val);   // 中
 traversal(cur->left, vec); // 左
 traversal(cur->right, vec); // 右

前序遍历完整代码

 class Solution {
 public:
     void traversal(TreeNode* cur, vector<int>& vec) {
         if (cur == NULL) return;
         vec.push_back(cur->val);    // 中
         traversal(cur->left, vec);  // 左
         traversal(cur->right, vec); // 右
    }
     vector<int> preorderTraversal(TreeNode* root) {
         vector<int> result;
         traversal(root, result);
         return result;
    }
 };//后序和中序遍历只需要把交换三个节点位置即可完成

四、二叉树迭代法遍历(栈结构)

 //前序遍历:中左右
 class Solution {
 public:
     vector<int> preorderTraversal(TreeNode* root) {
         stack<TreeNode*> st;
         vector<int> result;
         if (root == NULL) return result;
         st.push(root);
         while (!st.empty()) {
             TreeNode* node = st.top();                       // 中
             st.pop();
             result.push_back(node->val);
             if (node->right) st.push(node->right);           // 右 栈先进后出
             if (node->left) st.push(node->left);             // 左
        }
         return result;
    }
 };
 ​
 //后序遍历:左右中 === 中左右->中右左->左右中
 class Solution {
 public:
     vector<int> postorderTraversal(TreeNode* root) {
         stack<TreeNode*> st;
         vector<int> result;
         if (root == NULL) return result;
         st.push(root);
         while (!st.empty()) {
             TreeNode* node = st.top();            //中
             st.pop();
             result.push_back(node->val);
             if (node->left) st.push(node->left); // 左
             if (node->right) st.push(node->right); // 右
        }
         reverse(result.begin(), result.end()); // 将结果反转之后就是左右中的顺序了
         return result;
    }
 };
 ​
 //中序遍历
 class Solution {
 public:
     vector<int> inorderTraversal(TreeNode* root) {
         vector<int> result;
         stack<TreeNode*> st;
         TreeNode* cur = root;
         while (cur != NULL || !st.empty()) {
             if (cur != NULL) {
                 st.push(cur);
                 cur = cur->left;                // 左
            } else {
                 cur = st.top();
                 st.pop();
                 result.push_back(cur->val);     // 中
                 cur = cur->right;               // 右
            }
        }
         return result;
    }
 };

五、三种遍历的统一迭代法

 //根据栈结构先进后出的特性,前序、后序和中序遍历三者互换只需交换备注三行代码即可
 //前序遍历
 class Solution {
 public:
     vector<int> preorderTraversal(TreeNode* root) {
         vector<int> result;
         stack<TreeNode*> st;
         if (root != NULL) st.push(root);
         while (!st.empty()) {
             TreeNode* node = st.top();
             if (node != NULL) {
                 st.pop();
                 if (node->right) st.push(node->right);  // 右
                 if (node->left) st.push(node->left);    // 左
                 st.push(node);                          // 中
                 st.push(NULL);
            } else {
                 st.pop();
                 node = st.top();
                 st.pop();
                 result.push_back(node->val);
            }
        }
         return result;
    }
 };

六、层序遍历(队列)

 //层序遍历模板,后序很多用层序遍历的模板只需在此基础上做出小修改
 class Solution {
 public:
     vector<vector<int>> levelOrder(TreeNode* root) {
         queue<TreeNode*> que;
         if (root != NULL) que.push(root);
         vector<vector<int>> result;
         while (!que.empty()) {
             int size = que.size();
             vector<int> vec;
             // 这里要使用固定大小size,不要使用que.size(),因为que.size是不断变化的
             for (int i = 0; i < size; i++) {
                 TreeNode* node = que.front();
                 que.pop();
                 vec.push_back(node->val);
                 if (node->left) que.push(node->left);
                 if (node->right) que.push(node->right);
            }
             result.push_back(vec);
        }
         return result;
    }
 };
 
 
此页面的语言为中文(简体)
 
翻译为
 
 
 
 
  • 中文(简体)
  • 中文(繁体)
  • 丹麦语
  • 乌克兰语
  • 乌尔都语
  • 亚美尼亚语
  • 俄语
  • 保加利亚语
  • 克罗地亚语
  • 冰岛语
  • 加泰罗尼亚语
  • 匈牙利语
  • 卡纳达语
  • 印地语
  • 印尼语
  • 古吉拉特语
  • 哈萨克语
  • 土耳其语
  • 威尔士语
  • 孟加拉语
  • 尼泊尔语
  • 布尔语(南非荷兰语)
  • 希伯来语
  • 希腊语
  • 库尔德语
  • 德语
  • 意大利语
  • 拉脱维亚语
  • 挪威语
  • 捷克语
  • 斯洛伐克语
  • 斯洛文尼亚语
  • 旁遮普语
  • 日语
  • 普什图语
  • 毛利语
  • 法语
  • 波兰语
  • 波斯语
  • 泰卢固语
  • 泰米尔语
  • 泰语
  • 海地克里奥尔语
  • 爱沙尼亚语
  • 瑞典语
  • 立陶宛语
  • 缅甸语
  • 罗马尼亚语
  • 老挝语
  • 芬兰语
  • 英语
  • 荷兰语
  • 萨摩亚语
  • 葡萄牙语
  • 西班牙语
  • 越南语
  • 阿塞拜疆语
  • 阿姆哈拉语
  • 阿尔巴尼亚语
  • 阿拉伯语
  • 韩语
  • 马尔加什语
  • 马拉地语
  • 马拉雅拉姆语
  • 马来语
  • 马耳他语
  • 高棉语
 
随时将中文(简体)翻译为PRO
一律不翻译中文(简体)
一律不翻译i.cnblogs.com

LeetCode刷题知识点总结——二叉树的更多相关文章

  1. LeetCode刷题专栏第一篇--思维导图&时间安排

    昨天是元宵节,过完元宵节相当于这个年正式过完了.不知道大家有没有投入继续投入紧张的学习工作中.年前我想开一个Leetcode刷题专栏,于是发了一个投票想了解大家的需求征集意见.投票于2019年2月1日 ...

  2. LeetCode刷题总结-树篇(下)

    本文讲解有关树的习题中子树问题和新概念定义问题,也是有关树习题的最后一篇总结.前两篇请参考: LeetCode刷题总结-树篇(上) LeetCode刷题总结-树篇(中) 本文共收录9道题,7道中等题, ...

  3. LeetCode刷题的一点个人建议和心得

    目录 1.    为什么我们要刷LeetCode? 2.    LeetCode的现状和问题 3.    本文的初衷 4.    LeetCode刷题建议 4.1入门数据结构,打基础阶段 4.2 建立 ...

  4. 牛客网Java刷题知识点之Map的两种取值方式keySet和entrySet、HashMap 、Hashtable、TreeMap、LinkedHashMap、ConcurrentHashMap 、WeakHashMap

    不多说,直接上干货! 这篇我是从整体出发去写的. 牛客网Java刷题知识点之Java 集合框架的构成.集合框架中的迭代器Iterator.集合框架中的集合接口Collection(List和Set). ...

  5. 牛客网Java刷题知识点之HashMap的实现原理、HashMap的存储结构、HashMap在JDK1.6、JDK1.7、JDK1.8之间的差异以及带来的性能影响

    不多说,直接上干货! 福利 => 每天都推送 欢迎大家,关注微信扫码并加入我的4个微信公众号:   大数据躺过的坑      Java从入门到架构师      人工智能躺过的坑          ...

  6. 牛客网Java刷题知识点之Java 集合框架的构成、集合框架中的迭代器Iterator、集合框架中的集合接口Collection(List和Set)、集合框架中的Map集合

    不多说,直接上干货! 集合框架中包含了大量集合接口.这些接口的实现类和操作它们的算法. 集合容器因为内部的数据结构不同,有多种具体容器. 不断的向上抽取,就形成了集合框架. Map是一次添加一对元素. ...

  7. 牛客网Java刷题知识点之泛型概念的提出、什么是泛型、泛型在集合中的应用、泛型类、泛型方法、泛型接口、泛型限定上限、泛型限定下限、 什么时候使用上限?泛型限定通配符的体现

    不多说,直接上干货! 先来看个泛型概念提出的背景的例子. GenericDemo.java package zhouls.bigdata.DataFeatureSelection; import ja ...

  8. LeetCode刷题总结-树篇(中)

    本篇接着<LeetCode刷题总结-树篇(上)>,讲解有关树的类型相关考点的习题,本期共收录17道题,1道简单题,10道中等题,6道困难题. 在LeetCode题库中,考察到的不同种类的树 ...

  9. LeetCode刷题总结-树篇(上)

          引子:刷题的过程可能是枯燥的,但程序员们的日常确不乏趣味.分享一则LeetCode上名为<打家劫舍 |||>题目的评论: 如有兴趣可以从此题为起点,去LeetCode开启刷题之 ...

随机推荐

  1. AC+AP组网无线WiFi网速超慢延迟卡顿问题解决

    AP是什么? AP是Access Point的简称,即无线接入点,其作用是把局域网里通过双绞线传输的有线信号(即电信号)经过编译,转换成无线电信号传递给电脑.手机等无线终端,与此同时,又把这些无线终端 ...

  2. 『现学现忘』Docker基础 — 25、Docker镜像讲解

    目录 1.镜像是什么 2.Docker镜像获取的方式 3.Docker镜像加载原理 (1)UnionFS(联合文件系统) (2)Docker镜像加载原理 1.镜像是什么 镜像是一种轻量级.可执行的独立 ...

  3. Centos7 环境下设置固定IP

    1. 在/etc/sysconfig/network-scripts/下创建ifcfg-eth0配置文件, 并填入以下内容: DEVICE=eth0 TYPE=Ethernet IPADDR=192. ...

  4. 终结初学者对ElasticSearch、Kibana、Logstash安装的种种困难

    项目中准备使用ElasticSearch,之前只是对ElasticSearch有过简单的了解没有系统的学习,本系列文章将从基础的学习再到深入的使用. 咔咔之前写了一份死磕MySQL文章,如今再入一个系 ...

  5. SQL语句优化、mysql不走索引的原因、数据库索引的设计原则

    SQL语句优化 1 企业SQL优化思路 1.把一个大的不使用索引的SQL语句按照功能进行拆分 2.长的SQL语句无法使用索引,能不能变成2条短的SQL语句让它分别使用上索引. 3.对SQL语句功能的拆 ...

  6. _u32定义

    驱动开发的原则: 能用__u32就最好用它,或者用u_int32_t之类的也可以,但不要直接用unsigned int等默认的数据类型.目的是让别人明白,你这个变量占多大内存. 原因: 1.你不能确定 ...

  7. Redis+Caffeine两级缓存,让访问速度纵享丝滑

    原创:微信公众号 码农参上,欢迎分享,转载请保留出处. 在高性能的服务架构设计中,缓存是一个不可或缺的环节.在实际的项目中,我们通常会将一些热点数据存储到Redis或MemCache这类缓存中间件中, ...

  8. Spring两种注入方式

    1.XML注入 2.标签注入

  9. synchronized和Lock的区别是什么?

    原创2020-11-19 11:38:29011024区别:1.lock是一个接口,而synchronized是java的一个关键字.2.synchronized在发生异常时会自动释放占有的锁 ...

  10. String--int互转

    A:int -->String 1.String s1 = "" + 100; 2.String s2 = String.valueof(100); 3.(int -- In ...