一、二叉树理论基础
二叉树的种类
满二叉树
一个二叉树只有度为 0 或度为 2 的节点,并且度为 0 的节点都在同一层上,深度为 k,有 2^k - 1 个节点
完全二叉树
除了最底层没有填满,其余层的节点都填满,并且最底层的节点都集中在最左边,最底层,有 1 到 2^(k - 1)个节点
二叉搜索树
二叉搜索树是一个有序树,如果左子树不为空,则左子树上的所有节点的值均小于根节点的值,如果右子树不为空,则右子树上的所有节点的值均大于根节点的值,左右子树也均为二叉搜索树
平衡二叉搜索树
一个空树或者左右子树的高度差不超过 1,并且左右子树都是平衡二叉搜索树
二叉树的存储方式
链式存储
用指针,节点内存地址通过指针链接
顺序存储
用数组,内存地址连续,父节点的索引为 i,左子结点的索引为2 * i+ 1,右子节点的索引为2 * i + 2
二叉树的遍历方式
深度优先遍历
先往深走,遇到叶子节点再往回走
包括以下三种,主要根据中间节点的顺序判断
前序遍历,中左右
中序遍历,左中右
后序遍历,左右中
广度优先遍历
一层一层的遍历
function TreeNode(val = 0, left = null, right = null) {
this.val = val;
this.left = left;
this.right = right;
}
二、递归遍历
前序遍历
/**
* Definition for a binary tree node.
* function TreeNode(val, left, right) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
*/
/**
* @param {TreeNode} root
* @return {number[]}
*/
var preorderTraversal = function (root) {
let result = [];
function dfs(root) {
if (!root) {
return;
}
result.push(root.val);
dfs(root.left);
dfs(root.right);
}
dfs(root);
return result;
};
后序遍历
/**
* Definition for a binary tree node.
* function TreeNode(val, left, right) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
*/
/**
* @param {TreeNode} root
* @return {number[]}
*/
var postorderTraversal = function(root) {
let result = []
function dfs(root) {
if(!root) {
return
}
dfs(root.left)
dfs(root.right)
result.push(root.val)
}
dfs(root)
return result
};
中序遍历
/**
* Definition for a binary tree node.
* function TreeNode(val, left, right) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
*/
/**
* @param {TreeNode} root
* @return {number[]}
*/
var inorderTraversal = function(root) {
let result = []
function dfs(root) {
if(!root) {
return
}
dfs(root.left)
result.push(root.val)
dfs(root.right)
}
dfs(root)
return result
};
三、迭代遍历
前序遍历
var preorderTraversal = function(root) {
if(!root) {
return []
}
let result = []
let stack = [root]
while(stack.length) {
node = stack.pop()
result.push(node.val)
if(node.right) {
stack.push(node.right)
}
if(node.left) {
stack.push(node.left)
}
}
return result
};
中序遍历
var inorderTraversal = function(root) {
if(!root) {
return []
}
let result = []
let stack = []
let cur = root
while(stack.length || cur) {
if(cur) {
stack.push(cur)
cur = cur.left
} else {
let node = stack.pop()
result.push(node.val)
cur = node.right
}
}
return result
};
后续遍历
var postorderTraversal = function(root) {
let result = []
let stack = []
let cur = root
let prev = null
while(stack.length || cur) {
if(cur) {
stack.push(cur)
cur = cur.left
} else {
let node = stack.pop()
if(!node.right || node.right === prev) {
result.push(node.val)
prev = node
cur = null
} else {
stack.push(node)
cur = node.right
}
}
}
return result
};
四、统一迭代
标记法
前序遍历
/**
* Definition for a binary tree node.
* function TreeNode(val, left, right) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
*/
/**
* @param {TreeNode} root
* @return {number[]}
*/
var preorderTraversal = function (root) {
let result = []
let stack = []
if (root) {
stack.push(root)
}
while (stack.length) {
let node = stack.pop()
if (!node) {
result.push(stack.pop().val)
continue
}
if (node.right) {
stack.push(node.right)
}
if (node.left) {
stack.push(node.left)
}
stack.push(node)
stack.push(null)
}
return result
};
中序遍历
/**
* Definition for a binary tree node.
* function TreeNode(val, left, right) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
*/
/**
* @param {TreeNode} root
* @return {number[]}
*/
var inorderTraversal = function(root) {
let stack = []
let result = []
if(root) {
stack.push(root)
}
while(stack.length) {
let node = stack.pop()
if(!node) {
result.push(stack.pop().val)
continue
}
if(node.right) {
stack.push(node.right)
}
stack.push(node)
stack.push(null)
if(node.left) {
stack.push(node.left)
}
}
return result
};
后序遍历
/**
* Definition for a binary tree node.
* function TreeNode(val, left, right) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
*/
/**
* @param {TreeNode} root
* @return {number[]}
*/
var postorderTraversal = function(root) {
let stack = []
let result = []
if(root) {
stack.push(root)
}
while(stack.length) {
let node = stack.pop()
if(!node) {
result.push(stack.pop().val)
continue
}
stack.push(node)
stack.push(null)
if(node.right) {
stack.push(node.right)
}
if(node.left) {
stack.push(node.left)
}
}
return result
};