每日练习之二叉树

二叉树基本操作学习记录

二叉树的递归:先中后序
    //前序法
	public static void preamble(Node node) {
		if(node==null) {
			return;
		}
		System.out.print(node.value+" ");
		Node.preamble(node.left);
		Node.preamble(node.right);
	}
	//中序法
	public static void inorder(Node node) {
		if(node==null) {
			return;
		}
		Node.preamble(node.left);
		System.out.print(node.value+" ");
		Node.preamble(node.right);
	}
	//后序法
	public static void postorder(Node node) {
		if(node==null) {
			return;
		}
		Node.preamble(node.left);
		Node.preamble(node.right);
		System.out.print(node.value+" ");
	}
二叉树非递归:先中后序

先序:先将头节点放入栈中,再将头结点弹出,对弹出的节点处理,在压入右节点,再压入左节点。
中序:将左边界存入栈中,当无左边界节点存入是在执行弹栈,对弹出的节点处理,并且将它的右节点视为左边界存入栈中。
后序:先将头节点存入栈1中,在弹出节点,将弹出节点存入栈2中,最后将栈2弹栈,对弹出的节点处理。

//非递归前序法
	public static void preamble_stack(Node node) {
		if(node==null) {
			System.out.println("空树");
			return;
		}
		Stack stack=new Stack();
		//先将第一个节点放入栈中
		stack.push(node);
		//根据栈是否为空作为条件
		while(!stack.isEmpty()) {
			//弹栈,并且收弹出的元素
			Node popnode=(Node) stack.pop();
			//对弹出的元素操作
			System.out.print(popnode.value+" ");
			//判断弹出的元素的右子树
			if(popnode.right!=null) {
				stack.push(popnode.right);
			}
			//判断弹出的元素的左子树
			if(popnode.left!=null) {
				stack.push(popnode.left);
			}
		}
		
	}
	//非递归后序法
	public static void postorder_stack(Node node) {
		if(node==null) {
			System.out.println("空树");
			return;
		}
		//作为弹栈
		Stack stackpop=new Stack();
		//存储栈
		Stack stacksave=new Stack();
		
		stackpop.push(node);
		while(!stackpop.isEmpty()) {
			Node popnode=(Node) stackpop.pop();
			//对弹出的节点,存入stacksave中
			stacksave.push(popnode);
			if(popnode.left!=null) {
				stackpop.push(popnode.left);
			}
			if(popnode.right!=null) {
				stackpop.push(popnode.right);
			}
		}
		
		while(!stacksave.isEmpty()) {
			Node popnode=(Node) stacksave.pop();
			System.out.print(popnode.value+" ");
		}
	}
	//非递归中序法
	public static void inorder_stack(Node node) {
		if(node==null) {
			System.out.println("空树");
			return;
		}
		//先将左边所有的节点放入栈中
		Stack stack=new Stack();
		Node cur=node;
		stack.push(cur);
		while(!stack.isEmpty()) {
			//判断当前左节点是否为空
			if(cur.left!=null) {
				cur=cur.left;
				stack.push(cur);
			}else {
				//开始弹栈
				Node popnode=(Node) stack.pop();
				System.out.print(popnode.value+" ");
				//对弹出节点右节点判断如果不为空,入栈,并且将cur设置为右节点,将它视为开始时的左边界。
				if(popnode.right!=null) {
					stack.push(popnode.right);
					cur=popnode.right;
				}
			}
		}
	}
二叉树宽度优先遍历:常见题目求二叉树的宽度

第一个面临的问题:如何判断节点是第几层?取得出队列节点的层数,出队列节点的左右子树层数为出队列节点层数加1。左右子树必是第二层。
第二个面临的问题:如何计算每层的节点数?设置一个当前层,这个当前层是1,然后拿到出队列的节点层数,比较当前层与节点层是否相同,如果相同表示当前层的节点数+1,如果不相同表示出队列的节点层会大于当前层,并且当前层的节点数已计算完,这时可以比较最大值,将当前层+1。

public static int maxwidth(Node node) {
		if(node==null) {
			return 0;
		}
		int max=Integer.MIN_VALUE;//最大宽度
		int curLevel=1;//当前层
		HashMap<Node,Integer> map=new HashMap();//存放每个节点的层数
		map.put(node,1);
		int curLevelNodes=0;//当前层的节点个数
		Queue<Node> queue=new LinkedList();
		queue.add(node);
		while(!queue.isEmpty()) {
			Node curNode=queue.poll();
			int curNodeLevel=map.get(curNode);//取得当前节点的层数
			//取得当前层的节点数,
			if(curNodeLevel==curLevel) {
				curLevelNodes++;
			}else {
				max=Math.max(max, curLevelNodes);
				curLevel++;
				curLevelNodes=1;
			}
			
			//将左右子树入队列,并且设置层数
			if(curNode.left!=null) {
				queue.add(curNode.left);
				map.put(curNode.left, curNodeLevel+1);
			}
			if(curNode.right!=null) {
				queue.add(curNode.right);
				map.put(curNode.right, curNodeLevel+1);
			}
		}
		//1~n-1层中最大的数与第n层比较
		max=Math.max(max, curLevelNodes);
		return max;
	}

总结:关注点在当前层与节点层的关系,当前层只可能等于或小于节点层。等于说明当前层有这个节点,小于说明当前已经没有其他节点了。队列出队与入队是二叉数的宽度优先遍历。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值