文章目录
- 树的搜索
- 深度优先搜索(Deep First Search)
- 广度优先搜索(Breadth First Search)
- 树的遍历
- 前序遍历(PreOrder)
- 中序遍历(InOrder)
- 后序遍历(PostOrder)
树是一种常见的数据结构,由一系列节点和节点之间的关系组成。树的搜索和遍历是笔试和面试经常考的。最基本的树——二叉树,顾名思义,父节点最多只有两个子节点。我们先创建一个树节点类:
public class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) { val = x; }
}
树的搜索
深度优先搜索(Deep First Search)
深度优先搜索可以采用递归实现,代码如下:
List<Integer> visitList = new ArrayList();
public void dfs(TreeNode root){
if(root==null) return;
visitList.add(root.val);
dfs(root.left);
dfs(root.right);
}
当然,也可以非递归的方式,不过此时要借助栈来实现:
public void dfs(TreeNode root){
if(root==null){
return;
}
Stack<TreeNode > stack = new Stack<TreeNode >();
stack.push(node);
while(!stack.isEmpty()){
TreeNode rnode = stack.pop();
visitlist.add(rnode.val);
if(rnode.right!=null){
stack.push(rnode.right);
}
if(rnode.left!=null){
stack.push(rnode.left);
}
}
}
广度优先搜索(Breadth First Search)
广度优先搜索借助队列的FIFO特性实现,大致思路是:先搜索当前层的节点,然后将左子树和右子树添加到队列中,其Java代码如下(假设按层输出):
public List<List<Integer>> levelOrderBottom(TreeNode root) {
List<List<Integer>> res = new ArrayList();
Queue<TreeNode> queue = new LinkedList();
queue.add(root); //向队列中添加根节点
if(root==null) return res;
while(!queue.isEmpty()){
List<Integer> list = new ArrayList();
Queue<TreeNode> temp = new LinkedList();
while (!queue.isEmpty()) {
TreeNode n = queue.remove();
list.add(n.val);
if (n.left != null)
temp.add(n.left);
if (n.right != null)
temp.add(n.right);
}
queue = temp;
res.add(list);
}
return res;
}
树的遍历
数的遍历方式可以按照父节点、左子节点、右子节点的访问顺序不同分为以下三种:前序遍历,中序遍历,后序遍历。
前序遍历(PreOrder)
先访问父节点,再访问左子节点,最后访问右子节点。那么对于上面那张图对应的二叉树的遍历顺序依次为:1,2,4,5,3,6,7。可以发现,树的深度度优先搜索访问顺序和前序遍历是一样的。对应的Java代码如下:
List<Integer> visitList = new ArrayList();
public void preOrder(TreeNode root){
if(root==null) return;
visitList.add(root.val);
preOrder(root.left);
preOrder(root.right);
}
中序遍历(InOrder)
先访问左子节点,再访问父节点,最后访问右子节点。那么对于上面那张图对应的二叉树的遍历顺序依次为:4,2,5,1,6,3,7。对应的Java代码如下:
List<Integer> visitList = new ArrayList();
public void inOrder(TreeNode root){
if(root==null) return;
inOrder(root.left);
visitList.add(root.val);
inOrder(root.right);
}
后序遍历(PostOrder)
先访问左子节点,再访问右子节点,最后访问父节点。那么对于上面那张图对应的二叉树的遍历顺序依次为:4,5,2,6,7,3,1。对应的Java代码如下:
List<Integer> visitList = new ArrayList();
public void postOrder(TreeNode root){
if(root==null) return;
postOrder(root.left);
postOrder(root.right);
visitList.add(root.val);
}
不难发现,其实添加元素的位置的不同就对应了不同的遍历方式。