满二叉树
完全二叉树
二叉搜索树
有数值
是一个有序树
-
若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
-
若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
-
它的左、右子树也分别为二叉排序树、
左子树所有节点小于根结点,右子树所有节点大于根结点 -
如果是空节点 是不是二叉搜索树呢? 是的,二叉搜索树也可以为空!
-
二叉搜索树中序遍历一定是递增的,因此只需要判断当前节点值比上一个节点值大就好
平衡二叉搜索树(AVL(Adelson-Velsky and Landis)树)
它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树
- 堆的排序是父节点大于子节点,而搜索树是父节点大于左孩子,小于右孩子,所以堆不是平衡二叉搜索树
二叉树的存储方式
二叉树可以链式存储 指针
也可以顺序存储 数组
遍历方式
-
深度优先遍历:先往深走,遇到叶子节点再往回走。
前序遍历(递归法,迭代法)
中序遍历(递归法,迭代法)
后序遍历(递归法,迭代法) -
广度优先遍历:一层一层的去遍历。
层次遍历(迭代法
最小深度
最小深度是从根节点到最近叶子节点的最短路径上的节点数量。
dfs
递归可以看成是深度优先
bfs
层序遍历
二叉树节点的深度
指从根节点到该节点的最长简单路径边的条数。
二叉树节点的高度
指从该节点到叶子节点的最长简单路径边的条数。0
(想象成一颗数,高度就是从地面开始量的长度)
递归
如果需要遍历整棵树,递归函数就不能有返回值。
如果需要遍历某一条固定路线,递归函数就一定要有返回值
根据中序遍历和后续遍历的特性进行树的还原过程分析
- 首先在后序遍历序列中找到根节点(最后一个元素)
- 根据根节点在中序遍历序列中找到根节点的位置
- 根据根节点的位置将中序遍历序列分为左子树和右子树
- 根据根节点的位置确定左子树和右子树在中序数组和后续数组中的左右边界位置
- 递归构造左子树和右子树
- 返回根节点结束
通过位置序号索引更好
node.left = buildTree(is, ri - 1, ps, ps + ri - is - 1);
node.right = buildTree(ri + 1, ie, ps + ri - is, pe - 1);
根据中序遍历和前序遍历的特性进行树的还原过程分析
//左子树的长度 = 根节点索引-左子树
int leftNum=rootIndex-is;
TreeNode node=new TreeNode(root);
//递归构造左子树和右子树
node.left=two(preorder, ps+1,ps+leftNum+1,inorder,is,rootIndex);
node.right=two(preorder, ps+leftNum+1, pe, inorder,rootIndex+1,is);
在二叉树,递归函数究竟什么时候需要返回值,什么时候不要返回值?
如果要搜索一条边,递归函数就要加返回值
因为搜索到目标节点了,就要立即return了,这样才是找到节点就返回(搜索某一条边),如果不加return,就是遍历整棵树了。
二叉树遍历的迭代法
可能立刻想起使用栈来模拟深度遍历
使用队列来模拟广度遍历
取中间元素的位置 方法 不越界
首先取数组中间元素的位置,不难写出int mid = (left + right) / 2;,这么写其实有一个问题,就是数值越界,例如left和right都是最大int,这么操作就越界了,在二分法 (opens new window)中尤其需要注意!
所以可以这么写:
int mid = left + ((right - left) / 2)
;