IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 数据结构_第四讲 树的基本概念、二叉树、树和森林 -> 正文阅读

[数据结构与算法]数据结构_第四讲 树的基本概念、二叉树、树和森林

第四讲 树的基本概念、二叉树、树和森林

1. 树的基本概念

(1) 树是由根节点和若干颗子树构成的。树是由一个集合以及在该集合上定义的一种关系构成的。集合中的元素称为树的节点,所定义的关系称为父子关系。父子关系在树的节点之间建立了一个层次结构。在这种层次结构中有一个节点具有特殊的地位,这个节点称为该树的根节点,或称为树根。
(2) 空集合也是树,称为空树。空树中没有节点;
(3) 孩子节点或子节点:一个节点含有的子树的根节点称为该节点的子节点;
(4) 节点的度:一个节点含有的子节点的个数称为该节点的度;
(5) 叶节点或终端节点:度为0的节点称为叶节点;
(6) 非终端节点或分支节点:度不为0的节点;
(7) 双亲节点或父节点:若一个节点含有子节点,则这个节点称为其子节点的父节点;
(8) 兄弟节点:具有相同父节点的节点互称为兄弟节点;
(9) 树的度:一棵树中,最大的节点的度称为树的度;
(10) 节点的层次:从根开始定义起,根为第1层,根的子节点为第2层,以此类推;
(11) 树的高度或深度:树中节点的最大层次;
(12) 节点的祖先:从根到该节点所经分支上的所有节点;
(13) 子孙:以某节点为根的子树中任一节点都称为该节点的子孙;
(14) 森林:由棵互不相交的树的集合称为森林。

image-20210716201142018

理解理解理解

2. 二叉树

(1) 二叉树的定义及其主要特征
a. 二叉树的基本形态:空二叉树、单节点二叉树、左子树、右子树

? b. 性质:

? [1] 在非空二叉树中,第i层上至多有2^(i-1) 个结点。
? [2] 深度为k的二叉树至多有2^k - 1个结点
? [3] 对任何一颗二叉树,若其叶子结点数为n0,度为2的结点数为n2,则n0 = n2 + 1。
? [4] n个结点的完全二叉树深度为:log2(n)向下取整 + 1
? [5] 二叉树的堆式存储: 节点p (编号p)的左儿子:2p,右儿子:2p+1
?
? // r = [p/2]下取整

? c. 两种特殊的二叉树
? [1] 满二叉树:一颗深度为k且有2^k-1个结点的二叉树
? [2] 如果深度为k,有n个结点的二叉树,当且仅当其每个结点都与深度为k的满二叉树中编号从1到n的结点一一对应,该二叉树称为完全二叉树

(2) 二叉树的顺序存储结构和链式存储结构

? 链式存储结构
? /**c++:
? * Definition for a binary tree node.
? * struct TreeNode {
? * int val;
? * TreeNode *left;
? * TreeNode *right;
? * TreeNode(int x) : val(x), left(NULL), right(NULL) {}
? * };
? */
?

(3) 二叉树的遍历
a. 前序遍历 dfs
b. 中序遍历
c. 后序遍历
d. 根据前序 + 中序重建二叉树 (AcWing 18. 重建二叉树)
层次遍历不考 bfs

?

(4) 线索二叉树的基本概念和构造
? 对二叉树节点的指针域做如下规定:
? a. 若节点有左孩子,则Lchild指向左孩子,否则指向直接前驱;右孩子同理;
? b. 增加两个标志域,Ltag表示指向的是子节点还是前驱;Rtag同理
? c. 指向前驱和后继的指针叫做线索。按照某种次序遍历,加上线索的二叉树称之为线索二叉树

image-20210716203738956

image-20210716203854415

image-20210716204207520

n = n0 + n1 + n2

n-1边

n-1 = 0n0 + 1 * n1 + 2n 2

n0 + n1 + n2 - 1 == 0n0 + 1 * n1 + 2n 2

n0 - 1 == n 2

n0 = n2 + 1

1

前序+中序 —>> 构造二叉树

3. 树、森林

(1) 树的存储结构
a. 只存父节点
b. 邻接表存储所有子节点
c. 左儿子右兄弟
(2) 森林F二叉树T的转换
a. 原树中叶子节点数 = 转换后的树中有右儿子的节点数 + 1
b. F的前序遍历就是T的前序遍历
c. F的后序遍历就是T的中序遍历
(3) 树和森林的遍历
a. 前序遍历
b. 后序遍历

image-20210716213705277

4. 考题:2011-4、2011-5、2011-6、2012-3、2013-5、2014-4、2014-5、2014-41、2015-2、2016-5、2016-42、2017-4、2017-5、2018-4、2019-2、2020-3、2020-4

2011-4

image-20210717135246087

分析:求叶节点 n0

768 = n0+n1+n2

n0 = n2+1 ;

2*n2 +1 + n1 = 768

768 为偶数 n1 =1 ,多一个

2*n2 = 766

n2 = 383

n0 = n2+ 1 = 384 ;

2011-5

image-20210717135737523

前序和后序遍历 不能唯一确定 树

选择题 可以用 前序和 中序来判断

2011-6

image-20210718164805299

用结论 : 原树中叶子节点数 = 转换后的树中有右儿子的节点数 + 1

树中有右儿子的节点数 116 == 115 + 1

2011 - 115 = 1896

2012-3

image-20210718165530244

A

image-20210718165949376

2013-5

image-20210718170017054

A

后序线索二叉树:看后序遍历

线索二叉树:若节点有左孩子,则Lchild指向左孩子,否则指向直接前驱;右孩子同理

X 有 左兄弟 ,为叶节点 没有孩子

指向直接前驱 x 的父节点 yxp

image-20210718170548173

2014-4

image-20210718170726674

中序线索化:看中序遍历

debxac

选D

2014-5

image-20210718170914309

森林>>二叉树 左儿子 右兄弟

兄弟 == 儿子? yes

叶节点: 没有孩子

所以为没有左孩子的

选C

2014-41

image-20210718171711486

带权路径 : 权值* 到根节点的距离

AcWing 3766. 二叉树的带权路径长度

树的遍历 , 推荐dfs实现 即递归

image-20210718172227150

C++:

/**
 * 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:
    
    int dfs(TreeNode* root,int depth){  // depth 为深度
     if(!root) return 0;   //如果是空
     // 如果是叶节点: 没有左右孩子
     if(!root->left&&!root->right) return root->val*depth; 
     else {
         // 左右遍历 返回左右子树权值
         return dfs(root->left,depth+1)+ dfs(root->right,depth+1);
         
     }
     
    }


    int pathSum(TreeNode* root) {
        
        return dfs(root , 0);
    }
};

c:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */
int dfs(struct TreeNode* root,int depth){
    
    if(!root ) return 0;
    if(!root->left&&!root->right) return root->val*depth;
    else{
        
        return dfs(root->left,depth+1)+ dfs(root->right,depth+1);
        
    }
    
} 
 
int pathSum(struct TreeNode* root) {
    
    
return dfs(root , 0);

    
}

2015-2

image-20210718194045253

包含4个点的二叉树数量

N 卡特兰数

image-20210726210106380

2016-5

image-20210718194140386

25个结点 24条边

每删一条边多一颗树

删了24 - 15 = 9 棵

9+1 = 10 棵

2016-42

image-20210718194216798

归纳法:

n = nk+ n0

e = k* nk

e = n - 1

image-20210726211221536

image-20210726211338689

最多为满二叉树

2017-4

image-20210726211558663

B

image-20210726211658422

2017-5

image-20210726211724679

B

image-20210726211824779

2018-4

image-20210726211910620

满二叉树

image-20210726212632926

image-20210726212650654

2019-2

image-20210726211931557

B

2020-3

image-20210726211951141

要存下任意一棵树,最坏情况

1+2 +4 +8 +16 = 31

2^5-1 = 31

2020-4

image-20210726213032648

image-20210726213120328

5. 押题:AcWing 19

AcWing 19 二叉树的下一个节点

线索二叉树。

算法
(模拟) O(h)O(h)
这道题目就是让我们求二叉树中给定节点的后继。

分情况讨论即可,如下图所示:

1.如果当前节点有右儿子,则右子树中最左侧的节点就是当前节点的后继。比如F的后继是H;
2.如果当前节点没有右儿子,则需要沿着father域一直向上找,找到第一个是其father左儿子的节点,该节点的father就是当前节点的后继。比如当前节点是D,则第一个满足是其father左儿子的节点是F,则C的father就是D的后继,即F是D的后继。

image-20210726215002976

c++:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode *father;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL), father(NULL) {}
 * };
 */
class Solution {
public:
    TreeNode* inorderSuccessor(TreeNode* p) {
        // 1.如果当前节点有右儿子,则右子树中最左侧的节点就是当前节点的后继
        if(p->right) {
            p= p->right ;
            while(p->left ) p=p->left;
            return p;
        }
        
        // 2. 如果当前节点没有右儿子,则需要沿着father域一直向上找,找到第一个是其father左儿子的节点,该节点的father就是当前节点的后继。
        while(p->father&& p == p->father->right) p = p->father;
        return p->father;
        
        
    }
};
  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-07-27 16:29:50  更:2021-07-27 16:31:14 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/8 0:24:46-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码