树形结构

生活中的树形结构

树的基本概念1

其中子树可以从子节点的个数入手,如2节点的子树个数为2(见下图)

树的基本概念2

有序树,无序树,森林

二叉树

二叉树的性质

真二叉树

满二叉树

完全二叉树

完全二叉树的性质

完全二叉树高度与节点数之间的关系应该牢记,同时树上节点与其父节点、左子节点、右子节点编号之间的关系也应该牢记

上图编号从1开始,若编号从0开始(见下图),则公式有所变化,这个需要实际运用时灵活变通

做道面试题

这道题目使用好完全二叉树边数与节点数之间的关系,可以得出n0 = n2+1,还要注意的是完全二叉树的n1(度为1的节点数)要么是0要么是1。有上述分析,相信后面得出答案是十分简单的。
国外教材的说法

二叉树的遍历

前序遍历

前序遍历非递归实现
方法一:

方法二:

中序遍历

中序遍历非递归

后序遍历

后序遍历非递归

层序遍历

三种四则运算

表达式数

遍历的应用

刷几道leetcode题

方法一(深度优先搜索):
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public int maxDepth(TreeNode root) {
if(root == null)
return 0;
int lh = maxDepth(root.left);
int rh = maxDepth(root.right);
return Math.max(lh,rh)+1;
}
}
方法二(广度优先搜索):
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public int maxDepth(TreeNode root) {
if(root == null)
return 0;
Queue<TreeNode> queue = new LinkedList<TreeNode>();
queue.offer(root);
int ans = 0;
while(!queue.isEmpty()){
int size = queue.size();
while(size>0){
TreeNode node = queue.poll();
size--;
if(node.left!=null)
queue.offer(node.left);
if(node.right!=null)
queue.offer(node.right);
}
ans++;
}
return ans;
}
}

这题目跟上题其实十分类似,我这里就用一下深搜吧
提交的答案
class Solution {
public int countNodes(TreeNode root) {
if(root == null)
return 0;
int lnode_num = countNodes(root.left);
int rnode_num = countNodes(root.right);
return lnode_num + rnode_num + 1;
}
}

提交的答案
class Solution {
public TreeNode invertTree(TreeNode root) {
if(root == null)
return null;
TreeNode left = invertTree(root.left);
TreeNode right = invertTree(root.right);
root.right = left;
root.left = right;
return root;
}
}
重构二叉树

说白了就是能否根据遍历结果推出唯一的二叉树
通过先序或后序遍历确定根节点,并通过中序遍历的结果,就能确定左右子树的元素。这方面自己做几道例题都能清楚了。
二叉搜索树
二叉搜索树比起动态数组来说,时间复杂度上有了很大的优化(见下图)

二叉搜索树的性质

二叉树搜索树添加节点

删除度为0的叶子节点

删除度为1的节点

删除度为2的节点

前驱节点和后继节点
前驱节点:二叉树中序遍历时的前一个节点,二叉搜索树中左子树的最大节点
后继节点:二叉树中序遍历时的后一个节点,二叉搜索树中右子树的最小节点
平衡二叉搜索树
二叉搜索树存在一个问题,由于插入的顺序可能导致二叉搜索树退化成链表

由此引入了平衡的概念


二叉搜索树的改进


AVL树


添加导致的失衡

添加导致失衡的修复
下图中n的意思是node,p的意思是parent,g的意思是grandparent(添加导致失衡的节点)
LL指的是n在g的左左
LL可以通过对g进行右旋转修复(具体过程自己找视频看吧,文字难以解释)

RR的情况则对g节点进行左旋转

LR,先对p节点进行左旋转,再对g节点进行右旋转

RL,先对p节点进行右旋转,再对g节点进行左旋转

zig和zag

删除导致的失衡


失衡后的恢复同样是通过判断LL、RR、LR、RL四种情况进行恢复
AVL树总结

刷道leetcode

提交的答案
class Solution {
public int height(TreeNode root){
if(root == null)
return 0;
int lh = height(root.left);
int rh = height(root.right);
return Math.max(lh,rh) + 1;
}
public boolean isBalanced(TreeNode root) {
if(root == null)
return true;
return ((Math.abs(height(root.left) - height(root.right)) <= 1) && isBalanced(root.left) && isBalanced(root.right));
}
}
深入理解树形结构:二叉树与AVL树解析
文章详细介绍了树的基本概念,包括有序树和无序树,重点讨论了二叉树的各种类型如完全二叉树和满二叉树。阐述了完全二叉树的性质以及节点数与高度的关系,并提供了非递归遍历的方法。此外,文章还讲解了AVL树的平衡概念、失衡情况及修复策略,强调了其在优化搜索性能上的作用。

被折叠的 条评论
为什么被折叠?



