二叉树基础理论知识
-
二叉树的种类
(1)满二叉树
(2)完全二叉树
(3)二叉搜索树
(4)平衡二叉搜索树(AVL树):它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。 -
二叉树的存储方式
(1)链式存储:指针
(2)顺序存储:数组 -
二叉树的遍历方式
(1)深度优先遍历:
前序遍历(递归法,迭代法)
中序遍历(递归法,迭代法)
后序遍历(递归法,迭代法)
(2)广度优先遍历:
层次遍历(迭代法) -
递归三要素
(1)确定递归函数的参数和返回值:
确定哪些参数是递归的过程中需要处理的,那么就在递归函数里加上这个参数, 并且还要明确每次递归的返回值是什么进而确定递归函数的返回类型。
(2)确定终止条件:
写完了递归算法, 运行的时候,经常会遇到栈溢出的错误,就是没写终止条件或者终止条件写的不对,操作系统也是用一个栈的结构来保存每一层递归的信息,如果递归没有终止,操作系统的内存栈必然就会溢出。
(3)确定单层递归的逻辑:
确定每一层递归需要处理的信息。在这里也就会重复调用自己来实现递归的过程。
二叉树的递归遍历
前序遍历
题目链接:144. 二叉树的前序遍历
class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> list = new ArrayList<>();
preorder(root, list);
return list;
}
public void preorder(TreeNode node, List<Integer> list){
if(node == null){
return;
}
list.add(node.val);
preorder(node.left, list);
preorder(node.right, list);
}
}
中序遍历
题目链接:94. 二叉树的中序遍历
class Solution {
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> list = new ArrayList<>();
inorder(root, list);
return list;
}
public void inorder(TreeNode node, List<Integer> list){
if(node == null){
return;
}
inorder(node.left, list);
list.add(node.val);
inorder(node.right, list);
}
}
后序遍历
题目链接:145. 二叉树的后序遍历
class Solution {
public List<Integer> postorderTraversal(TreeNode root) {
List<Integer> list = new ArrayList<>();
postorder(root, list);
return list;
}
public void postorder(TreeNode node, List<Integer> list){
if(node == null){
return;
}
postorder(node.left, list);
postorder(node.right, list);
list.add(node.val);
}
}
二叉树的迭代遍历
前序遍历
题目链接:144. 二叉树的前序遍历
class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> list = new ArrayList<>();
if(root == null){
return list;
}
Stack<TreeNode> stack = new Stack<>();
stack.push(root);
while(!stack.isEmpty()){
TreeNode cur = stack.pop();
list.add(cur.val);
if(cur.right != null){
stack.push(cur.right);
}
if(cur.left != null){
stack.push(cur.left);
}
}
return list;
}
}
中序遍历
题目链接:94. 二叉树的中序遍历
class Solution {
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> list = new ArrayList<>();
Stack<TreeNode> stack = new Stack<>();
TreeNode cur = root;
while(cur != null || !stack.isEmpty()){
if(cur != null){
stack.push(cur);
cur = cur.left;
}
else{
cur = stack.pop();
list.add(cur.val);
cur = cur.right;
}
}
return list;
}
}
后序遍历
题目链接:145. 二叉树的后序遍历
先序遍历是中左右,后续遍历是左右中,那么我们只需要调整一下先序遍历的代码顺序,就变成中右左的遍历顺序,然后在反转result数组,输出的结果顺序就是左右中了。
class Solution {
public List<Integer> postorderTraversal(TreeNode root) {
List<Integer> list = new ArrayList<>();
if(root == null){
return list;
}
Stack<TreeNode> stack = new Stack<>();
stack.push(root);
while(!stack.isEmpty()){
TreeNode cur = stack.pop();
list.add(cur.val);
if(cur.left != null){
stack.push(cur.left);
}
if(cur.right != null){
stack.push(cur.right);
}
}
Collections.reverse(list);
return list;
}
}
二叉树的统一迭代法
迭代法实现前中后序遍历,是可以写出统一风格的代码的,但是比较难想到。这里就不贴代码了,把上面的方法掌握就可以了。