树的节点结构
public class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) { val = x; }
}
创建树
树的创建有多种方法,如通过遍历创建等,在此采用BFS方法创建树,其中结点为 -1 的点代表null。
public TreeNode CreateTree() {
int[] data = {3,9,20,-1,-1,15,7};
TreeNode root = new TreeNode(data[0]);
Queue<TreeNode> queue = new LinkedList<TreeNode>();
queue.add(root);
int num = 1;
while(num != 7)
{
TreeNode current = queue.poll();
if(data[num] != -1) {
current.left = new TreeNode(data[num]);
queue.add(current.left);
}
num++;
if(data[num] != -1) {
current.right = new TreeNode(data[num]);
queue.add(current.right);
}
num++;
}
return root;
}
深度优先遍历-DFS
深度优先遍历包括先序遍历、中序遍历和后序遍历
先序遍历
先序遍历的遍历顺序:根节点-左子树-右子树
对于结点 【3,9,20,-1,-1,15,7】,其树状图如下所示
前序遍历结果应为:3、9、20、15、7
- 递归实现
public void preOrder(TreeNode root) {
System.out.println(root.val);
TreeNode LeftNode = root.left;
if(LeftNode != null) {
preOrder(LeftNode);
}
TreeNode RightNode = root.right;
if(RightNode != null) {
preOrder(RightNode);
}
}
- 非递归实现
public void preOrder(TreeNode root)
{
Stack<TreeNode> stack = new Stack<TreeNode>();
while(root != null || !stack.isEmpty()) {
while(root != null) {
System.out.println(root.val);
stack.push(root);
root = root.left;
}
if(!stack.isEmpty()) {
root = stack.pop();
root = root.right;
}
}
}
中序遍历
中序遍历的遍历顺序:左子树-根节点-右子树
对于结点 【3,9,20,-1,-1,15,7】,其树状图如下所示
中序遍历结果应为:9、3、15、20、7
- 递归实现
public void midOrder(TreeNode root) {
if(root == null)
return;
else {
midOrder(root.left);
System.out.println(root.val);
midOrder(root.right);
}
}
- 非递归实现
public void midOrder(TreeNode root) {
Stack<TreeNode> stack = new Stack<TreeNode>();
while(root != null || !stack.isEmpty()) {
while(root != null) {
stack.push(root);
root = root.left;
}
if(!stack.isEmpty()) {
root = stack.pop();
System.out.println(root.val);
root = root.right;
}
}
}
后序遍历
后序遍历的遍历顺序:左子树-右子树-根节点
对于结点 【3,9,20,-1,-1,15,7】,其树状图如下所示
后序遍历结果应为:9、15、7、20、3
- 递归实现
public void postOrder(TreeNode root) {
if(root == null)
return;
else {
postOrder(root.left);
postOrder(root.right);
System.out.println(root.val);
}
}
- 非递归实现
public void postOrder(TreeNode root) {
int left = 1; //在辅助栈里表示左结点
int right = 2; //在辅助栈里表示右结点
Stack<TreeNode> stack = new Stack<TreeNode>();
Stack<Integer> judge = new Stack<Integer>(); //辅助栈,用来判断子节点返回父节点时处于左结点还是右节点
while(root != null || !stack.isEmpty()) {
while(root != null) {
stack.push(root);
judge.push(left);
root = root.left;
}
while(!stack.isEmpty() && judge.peek() == right) {
//如果是从右子节点返回父节点,则任务完成,将两个栈的栈顶弹出
judge.pop();
System.out.println(stack.pop().val);
}
if(!stack.empty() && judge.peek() == left) {
//如果是从左子节点返回父节点,则将标记改为右子节点
judge.pop();
judge.push(right);
root = stack.peek().right;
}
}
}
层次遍历-BFS
层次遍历的遍历顺序:左子树-右子树-根节点
对于结点 【3,9,20,-1,-1,15,7】,其树状图如下所示
层次遍历结果应为:3、9、20、15、7
public void levelOrder(TreeNode root) {
if(root == null)
return;
Queue<TreeNode>queue = new LinkedList<>();
queue.add(root);
TreeNode current;
while(!queue.isEmpty()) {
current = queue.poll();
System.out.println(current.val);
if(current.left != null)
queue.add(current.left);
if(current.right != null)
queue.add(current.right);
}
}