这是我参与11月更文挑战的第3天,活动详情查看:2021最后一次更文挑战
二叉树的遍历
递归的前中后序遍历
前序遍历
访问根节点——>根的左子树——>根的右子树
打印:A B D E H C F G
public void preOrderTraversal(Node root){
if(root == null){
return;
}
System.out.println(root);
preOrderTraversal(root.left);
preOrderTraversal(root.right);
}
返回list的前序遍历
public List<String> preOrderTraversal(Node root){
List<String> list = new LinkedList<>();
if(root == null){
//此处不能是null,因为addAllc的参数不能为null
return list;
}
list.add(root.getVal());
list.addAll(preOrderTraversal(root.left));
list.addAll(preOrderTraversal(root.right));
return list;
}
中序遍历
根的左子树——>访问根节点——>根的右子树
打印:D B E H A F C G
public void inpOrderTraversal(Node root){
if(root == null){
return;
}
preOrderTraversal(root.left);
System.out.print(root);
preOrderTraversal(root.right);
}
返回list的中序遍历
public List<String> inOrderTraversal(Node root){
List<String> list = new LinkedList<>();
if(root == null){
//此处不能是null,因为addAllc的参数不能为null
return list;
}
list.addAll(preOrderTraversal(root.left));
list.add(root.getVal());
list.addAll(preOrderTraversal(root.right));
return list;
}
后序遍历
根的左子树——>根的右子树——>访问根节点
打印:D H E B F G C A
public void postOrderTraversal(Node root){
if(root == null){
return;
}
preOrderTraversal(root.left);
preOrderTraversal(root.right);
System.out.print(root);
}
返回list的后序遍历
public List<String> postOrderTraversal(Node root){
List<String> list = new LinkedList<>();
if(root == null){
//此处不能是null,因为addAllc的参数不能为null
return list;
}
list.addAll(preOrderTraversal(root.left));
list.addAll(preOrderTraversal(root.right));
list.add(root.getVal());
return list;
}
非递归的前中后序遍历
前序遍历
递归转为非递归,用栈可以模拟递归的路线 cur指向根节点,来遍历整个树 如果cur不为null,将cur放入栈中,然后继续向左走,放入栈中的根节点用于在后面寻找其右树 当cur为空时,出栈顶元素(根节点)找到其右树,让cur 继续遍历其右树
public void preOrderTraversalNor(Node root) {
if (root == null) {
return;
}
Stack<Node> stack = new Stack<>();
Node cur = root;
while (cur != null || !stack.isEmpty()) {
while (cur != null) {
stack.push(cur);
System.out.print(cur);
cur = cur.left;
}
Node top = stack.pop();
cur = top.right;
}
}
中序遍历
public void inOrderTraversalNor(Node root) {
if (root == null) {
return;
}
Stack<Node> stack = new Stack<>();
Node cur = root;
while (cur != null || !stack.isEmpty()) {
while (cur != null) {
stack.push(cur);
cur = cur.left;
}
Node top = stack.pop();
System.out.print(top);
cur = top.right;
}
}
后序遍历(有点难哦)
-
同样的用cur指向根节点,遍历整个树
-
如果cur不为空,将cur放入栈中,然后cur继续遍历左树
-
当cur为空时,获取栈顶元素(仅获取,并不提出,因为此时并不能打印这个元素),cur指向栈顶元素
-
判断cur的右树是否为空,如果为空,提出栈顶元素(可以打印了),并将cur置空,继续第3步循环,同时,如果cur的右树被打印过,同样执行这个操作
-
如果cur右树不为空,让cur指向其右树的根节点,遍历右树,继续第2步的循环
public void postOrderTraversalNor(Node root){
if(root == null){
return;
}
Stack<Node> stack = new Stack<>();
Node cur = root;
Node pre = null; //用来指定上一次被打印的元素
while(cur != null || !stack.isEmpty()) {
while (cur != null) {
stack.push(cur);
cur = cur.left;
}
cur = stack.peek(); //必须是peek,不能是pop,不能过早的把D提出来,否则最后无法打印D了
if(cur.right == null || cur.right == pre){
Node popNode = stack.pop();
System.out.print(popNode);
pre = popNode;
cur = null;
}else{
cur = cur.right;
}
}
}
层序遍历
需要使用队列
- 判断A是否为空,如果为空,直接返回;如果不为空,将其放入到队列中
- 出队列的头元素并打印,这个根节点的左树不为空放左树根节点,右树不为空放右树根节点
- 继续循环
public void levelOrderTraversal(Node root){
if(root == null){
return;
}
Queue<Node> queue = new LinkedList<>();
queue.offer(root);
while(!queue.isEmpty()){
Node top = queue.poll();
System.out.print(top);
if(top.left != null){
queue.offer(top.left);
}
if(top.right != null){
queue.offer(top.right);
}
}
}
看威震天如何在洛杉矶湖人掀起狂风巨浪!!!!