算法day09 二叉树

class Node<V>{
    V  value;
    Node left;
    Node right;
}

一、用递归和非递归分别实现二叉树的前序,中序,后序遍历

        非递归方式:

 前序遍历  根左右

           0)利用stack后进先出的特点

                        要输出根左右的顺序,将元素右边先放入栈中元素左边后放入栈中,实现先弹出左边元素再弹出右边元素。

           1) 入栈顺序:

                              ①入栈,弹出;弹出的①视为根节点

                              每次while循环只看这一颗小树:

                               ③入栈,②入栈;

                                第二次while循环,弹出的②视为根节点:

                                ⑤入栈 , ④入栈

                                第三次while循环,弹出的④视为根节点:

                                没有元素入栈                      

                                第四次while循环,弹出的⑤视为根节点:

                                没有元素入栈

                                第五次while循环,弹出的③视为根节点:

                                ⑦入栈 ,  ⑥入栈

                                . . . . . .

              2)代码实现                  

import java.util.Stack;

public class Main {
    public static void main(String[] args) {
        TreeNode root = new TreeNode(1);
        root.left = new TreeNode(2);
        root.left.left = new TreeNode(4);
        root.left.right = new TreeNode(5);
        
        root.right = new TreeNode(3);
        root.right.left = new TreeNode(6);
        root.right.right = new TreeNode(7);

        System.out.println("Inorder Traversal:");
        InorderTraversal.inorderTraversal(root); 
    }
}

class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;
    TreeNode(int x) { val = x; }
}

class InorderTraversal {
    public static void inorderTraversal(TreeNode root) {
        Stack<TreeNode> stack = new Stack<>();
        TreeNode current = root;
        stack.push(current);

        while ( !stack.isEmpty()) {
            // while (current != null) {
            //     stack.push(current);
            //     current = current.left;
            // }
            // current = stack.pop();
            // System.out.print(current.val + " ");
            // current = current.right;
             current  =  stack.pop();
             System.out.print(current.val+ " ");
             
             if(current.right!=null){
                 stack.push(current.right);
             }
             
                if(current.left!=null){
                 stack.push(current.left);
             }
            
        }
    }
}


               中序遍历  左根右

                        实现左根右的输出,从根节点①加入栈开始,再将所有左节点元素②、④依次加入到栈中        

                        再根据栈的弹出找到最左边最先输出的树,

                                弹出④,再以④为根节点找④右子节点的元素,没有进入下次循环

                        每一次while循环只看根据栈的弹出的这一颗树

                                弹出②,这时根节点为②,找右子节点⑤

                        接着while循环以⑤为根节点

                                将从根节点⑤加入栈开始,如果⑤有左右节点的话,再将所有左节点元素加入到栈

                        . . . . . .

                        实质上发现while循环还是递归的另一种形式。

import java.util.Stack;

public class Main {
    public static void main(String[] args) {
        TreeNode root = new TreeNode(1);
        root.left = new TreeNode(2);
        root.left.left = new TreeNode(4);
        root.left.right = new TreeNode(5);
        
        root.right = new TreeNode(3);
        root.right.left = new TreeNode(6);
        root.right.right = new TreeNode(7);

        System.out.println("Inorder Traversal:");
        InorderTraversal.inorderTraversal(root); // Output should be 4 2 5 1 6 3 7
    }
}

class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;
    TreeNode(int x) { val = x; }
}

class InorderTraversal {
    public static void inorderTraversal(TreeNode root) {
        Stack<TreeNode> stack = new Stack<>();
        TreeNode current = root;
        

        while (current!=null || !stack.isEmpty()) {
            while (current != null) {
                stack.push(current);
                current = current.left;
            }
            current = stack.pop();
            System.out.print(current.val + " ");
            current = current.right;
            
        }
    }
}


              后序遍历  左右根

                        再前序遍历的基础上,每次弹栈出的元素放入到新栈中,就能实现将根左右转换为右左根的顺序。

                        实现左右根的顺序,只需要将原来的根左右变为根右左。

        

import java.util.Stack;

public class Main {
    public static void main(String[] args) {
        TreeNode root = new TreeNode(1);
        root.left = new TreeNode(2);
        root.left.left = new TreeNode(4);
        root.left.right = new TreeNode(5);
        
        root.right = new TreeNode(3);
        root.right.left = new TreeNode(6);
        root.right.right = new TreeNode(7);

        System.out.println("Inorder Traversal:");
        InorderTraversal.inorderTraversal(root); 
    }
}

class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;
    TreeNode(int x) { val = x; }
}

class InorderTraversal {
    public static void inorderTraversal(TreeNode root) {
        Stack<TreeNode> stack = new Stack<>();
        Stack<TreeNode> stack2 = new Stack<>();
        TreeNode current = root;
        stack.push(current);

        while ( !stack.isEmpty()) {
            // while (current != null) {
            //     stack.push(current);
            //     current = current.left;
            // }
            // current = stack.pop();
            // System.out.print(current.val + " ");
            // current = current.right;
             current  =  stack.pop();
             stack2.push(current);
            //  System.out.print(current.val+ " ");
             
             if(current.left!=null){
                 stack.push(current.left);
             }
             
                if(current.right!=null){
                 stack.push(current.right);
             }
            
        }
        while(!stack2.isEmpty()){
             System.out.print(stack2.pop().val);
        }
    }
}


二、直观的打印一颗二叉树                                                            



三、二叉树的宽度优先遍历 , 找层级最大节点数

             第一种方式:

                            1)实现层级遍历

                            2)哈希表记录每一节点对应的层级

                            3)统计每一层级对应节点数         

      

         第二种方式:

                      针对二叉树结构,使用队列,滚动更新变量。

                      定义四个变量:

                              currentEnd   null       当前层级最后节点对象

                              nextEnd    null           队列中最后一个节点对象

                              levelNum     0             当前层级节点数      

                              max    null            最大值 

                      遍历过程:从根节点①开始        

                              ①入栈:

                                        levelNum = 1

                                        current = ①        

                              ①出栈:左右孩子分别进栈                

                                        ②入栈, next = ②  

                                        ③入栈, next = ③ 

                                        ①和current相同:     

                                                max  =  levelNum

                                                levelNum = 0   //重置计数

                                                current =  next = ③

                                                next = null       //重置下一层级最后节点对象

                               ②出栈,孩子进队列

                                        ④入栈,next为④

                                        levelNum = 1

                                        ②与current不相同

                               ③出栈,孩子进队列

                                        ⑤入栈,next为⑤

                                        ⑥入栈,next为⑥

                                         levelNum++       

                                        ③与current相同:

                                                max  =  levelNum

                                                levelNum = 0  //重置计数

                                                current =  next = ⑥

                                                next = null       //重置下一层级最后节点对象

                              . . . . . .                         

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值