用栈的方式来实现二叉树的先、中、后序遍历

二叉树的遍历:

二叉树的递归遍历:
先创建一个树结构类

 public static class Node {
        public int value;
        public Node left;
        public Node right;

        public Node(int v) {
            value = v;
        }
    }

先,中,后序遍历

//先序遍历
public static void pre(Node head) {
        if (head == null) {
            return;
        }
        System.out.println(head.value);
        pre(head.left);
        pre(head.right);
    }
//中序遍历
    public static void in(Node head) {
        if (head == null) {
            return;
        }
        in(head.left);
        System.out.println(head.value);
        in(head.right);
    }
//后序遍历
    public static void pos(Node head) {
        if (head == null) {
            return;
        }
        pos(head.left);
        pos(head.right);
        System.out.println(head.value);
    }

用栈的方式来实现二叉树的先、中、后序遍历_第1张图片
根据代码,我们可以看出二叉树的遍历顺序为:
先访问A,从头节点A出发,先递归左边B,访问B节点;继续递归-访问D节点;D节点递归,发现没有子节点,返回到D节点;然后再访问D节点的右节点,发现也没有字节点,又返回到D节点,再返回到B节点。
得出顺序为;
A-B-D-D-D-B-E-E-E-B-A-C-F-F-F-C-C-A

根据先序遍历顺序:ABDECF
中序遍历:DBEAFC
后序遍历:DEBFCA

我们可以看出,当第一次访问节点时就输出的是先序遍历,第二次访问节点再输出的是中序遍历,第三次访问节点再输出的后序遍历。
所以 System.out.println(head.value);输出语句的顺序就可以决定是先序,中序,还是后序遍历

二叉树的非递归调用:
在这里我们使用栈来实现

先序遍历

public static void pre(Node head) {
		System.out.print("pre-order: ");
		if (head != null) {//当二叉树存在意义才进行操作
			Stack<Node> stack = new Stack<Node>();//创建一个栈来存储数据
			stack.add(head);//首先将头节点进行压栈
			while (!stack.isEmpty()) {//当栈里面有值,说明二叉树还没有遍历结束
				head = stack.pop();//将值弹出
				System.out.print(head.value + " ");
				//这里是先先压右节点,再压左节点。
				//因为栈是先进后出,最后输出的顺序是左节点,右节点
				if (head.right != null) {
					stack.push(head.right);//存在右将右节点压入栈
				}
				if (head.left != null) {
					stack.push(head.left);//存在左节点则将左节点压入栈
				}
			}
		}
		System.out.println();
	}

上几张自己的丑图
用栈的方式来实现二叉树的先、中、后序遍历_第2张图片
用栈的方式来实现二叉树的先、中、后序遍历_第3张图片
用栈的方式来实现二叉树的先、中、后序遍历_第4张图片
如此反复循环下去,直到没有子节点位置

后序遍历:

//这里我们先遍历左孩子,再遍历右孩子。得到头-右-左。
//我们将它逆序就是左-右-头,这就是一个后序遍历。
//因为逆序的话,我们就需要两个栈才能完成
public static void pos1(Node head) {
		System.out.print("pos-order: ");
		if (head != null) {
			Stack<Node> s1 = new Stack<Node>();
			Stack<Node> s2 = new Stack<Node>();
			s1.push(head);//一样先将头节点压栈
			while (!s1.isEmpty()) {//栈里面有数据就循环
				head = s1.pop();//弹出栈里面的数据
				s2.push(head);//放到备用栈,用来逆序
				//下面这些步骤和先序遍历一样,只是顺序不一样
				if (head.left != null) {
					s1.push(head.left);
				}
				if (head.right != null) {
					s1.push(head.right);
				}
			}
			while (!s2.isEmpty()) {
				System.out.print(s2.pop().value + " ");
			}
		}
		System.out.println();
	}

中序遍历:
我们每次都先遍历左节点,并且遍历到第,直到它为空,再遍历右节点的左孩子。
类似这样子
用栈的方式来实现二叉树的先、中、后序遍历_第5张图片


	public static void in(Node head) {
		System.out.print("in-order: ");
		if (head != null) {//二叉树有意义再进行操作
			Stack<Node> stack = new Stack<Node>();//用来存放二叉树
			while (!stack.isEmpty() || head != null) {
				if (head != null) {//先将头节点最左侧的数据压栈
					stack.push(head);
					head = head.left;
				} else {//当节点为空时,栈里面就弹出一个数据,
				//并且head开始指向右节点,去遍历右节点中的左孩子
					head = stack.pop();
					System.out.print(head.value + " ");
					head = head.right;
				}
			}
		}
		System.out.println();
	}

今日任务

找错误:
问题描述,当输入一个能查到的数字时,再输入不能查到的数据时,
不能按照我们想要的结束循环,它会一直循环下去
/**
     * 在数组{4,5,6,2,3,1,9,8,7,10,12,14,15}中查找元素
     * (先打印输出所有元素,输入一个数,如果找到了则打印输出其位置,
     * 没有找到则提示没有找到)
     */
    public static void Test8(){
            int count = 0;
            int index = 0;
            int arr[] = {4,5,6,2,3,1,9,8,7,10,12,14,15};
            Scanner scanner = new Scanner(System.in);
            System.out.println("数组中的数有:"+Arrays.toString(arr));
            while(true){
                System.out.println("请输入数字:");
                int number = scanner.nextInt();
                for (int i = 0; i < arr.length; i++) {
                    if(number==arr[i]){
                        System.out.println("能找到,它的下标为"+i);
                        count++;
                    }
                }
                if(count==0){
                    System.out.println("没有找到!");
                    break;
                }
            }
        }

栈内操作为:
先获取头节点,压入栈内

问题所在:
当我们第一次输入正确的值时count++,此时count=1;当进行下一个循环时,count没有初始化,还是>0的数。所以后面无论再输入何数,count==0的条件都不会成立。我们在每次while循环的时候,都将count设置为0,这样就可以达到预期效果。
修改后的代码:

  public static void Test8(){
            int count = 0;
            int index = 0;
            int arr[] = {4,5,6,2,3,1,9,8,7,10,12,14,15};
            Scanner scanner = new Scanner(System.in);
            System.out.println("数组中的数有:"+Arrays.toString(arr));
            while(true){
                count = 0;
                System.out.println("请输入数字:");
                int number = scanner.nextInt();
                for (int i = 0; i < arr.length; i++) {
                    if(number==arr[i]){
                        System.out.println("能找到,它的下标为"+i);
                        count++;
                    }
                }
                if(count==0){
                    System.out.println("没有找到!");
                    break;
                }
            }
        }

你可能感兴趣的:(算法与数据结构,java,算法,数据结构)