二叉树学习

二叉树节点结构

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

用递归和非递归两种方式实现二叉树的先序、中序、后序遍历
二叉树宽度

递归序列

递归的顺序,先遍历左侧走到头碰到null,就往回左右遍历。
先序打印节点(头左右):1,2,4,5,3,6,7
中序(左头右):4,2,5,1,6,3,7
后序(左右头):4,5,2,6,7,3,1
在这里插入图片描述

class Node<V>{
		V value;
		Node left;
		Node right;
	}
	public void f(Node head){//递归
		if (head==null){
			return;
		}
		f(head.left);
		f(head.right);
	}
	public void pre(Node head){//前序遍历
		if(head==null){
			return;
		}
		System.out.print(head.value);
		pre(head.left);
		pre(head.right);
	}
	public void mid(Node head){//中序遍历
		if(head==null){
			return;
		}
		mid(head.left);
		System.out.print(head.value);//只在他来到第二个节点打印值
		mid(head.right);
	}
	public static void main(String[] args) {
		
	}

非递归

前序思想:

  1. 进入头节点,弹出
  2. 进入左右子节点,弹出

在这里插入图片描述
中序思想:
方法1:
3. 构建两个栈,收集栈存放弹出的节点
4. 先做后右
5. 最后弹出收集栈的节点即为中序遍历
方法2:
6. 将左子树都进栈,然后弹出节点
7. 判断弹出节点是否有右子节点,有就进栈,
8. 然后判断是否有左子节点,全部进栈,然后弹出在这里插入图片描述
在这里插入图片描述
9. 方法2原理:整棵树都可以看成左倾,一直在做“左头”,右子树也在做“左头”操作,就忽略“右概念”了。

public void pre1(Node head){//先序遍历
		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);//先压右
				}
			}
		}
	}

	public void mid1(Node head){//中序法1
		if (head!=null){
			Stack<Node> stack=new Stack<Node>();//准备一个栈
			Stack<Node> stack1=new Stack<Node>();//准备一个栈
			stack.add(head);//先把头结点压入到占中
			while(!stack.isEmpty()){
				head=stack.pop();//弹出节点
				stack1.push(head);
				if(head.left!=null){
					stack.push(head.left);//先压左
				}
				if(head.right!=null){
					stack.push(head.right);//先压右
				}
			}
			while(!stack1.isEmpty()){
				System.out.print(stack1.pop());
			}
		}
	public void mid2(Node head){//法2:
		if (head!=null){
			Stack<Node> stack=new Stack<Node>();//准备一个栈
			//如何将所有左子树进栈?不会。
			while(!stack.isEmpty()||head!=null){
				if(head!=null){//老师思路:周而复始使左子树进栈,移动head.left,最终会到达一个null,就结束循环
					stack.push(head);
					head=head.left;
				}else{
					head=stack.pop();
					System.out.print(head.value);
					head=head.right;//结束后进栈,跳到条件一判断是否有左节点
				}
				
			}
			
		}
	}

宽度遍历

思想:额外空间:队列

  • 先进左后进右
  • 弹出节点,判断该节点是否有子节点,进队列在这里插入图片描述
public  void w(Node head){//宽度遍历
		if(head==null){
			return;
		}
		Queue<Node> queue=new LinkedList<>();//双向链表可以当做队列用
		queue.add(head);
		while(!queue.isEmpty()){
			Node cur=queue.poll();
			System.out.print(cur.value);
			if(cur.left!=null){//先放左
				queue.add(cur.left);
			}if (cur.right!=null){//后放右
				queue.add(cur.right);
			}
		}
	}

题目:判断二叉树中哪一层节点最多?

问题:需要找出第几层,有几个节点
提示:准备一张哈希表(key为节点,value为节点个数)
思想:

  • 准备一张哈希表(key为节点,value为节点个数)
  • 初始化话当前层、当前层节点数
  • 首先根据宽度遍历思想,队列操作
  • 弹出节点时(对应层数map中的value)判断该节点是否属于当前层,属于就节点+1,不属于就比较节点数,初始化当前节点数,层数+1
public  void w(Node head){
		if(head==null){
			return;
		}
		Queue<Node> queue=new LinkedList<>();//双向链表可以当做队列用
		queue.add(head);
		HashMap<Node,Integer> levelmap=new HashMap<>();
		levelmap.put(head, 1);//头节点在第一层
		int curlevel=1;//当前层
		int curlevelNodes=0;//当前层有几个节点
		int max=Integer.MIN_VALUE;//最大的一层
		
		while(!queue.isEmpty()){
			Node cur=queue.poll();
			int curNodelevel=levelmap.get(cur);//弹出一个节点得到节点层数map中的value
			if(curNodelevel==curlevel){
				curlevelNodes++;//弹出的节点层与当前统计层一样,就+1一个节点
			}else{//当前层结束
				max=Math.max(max,curlevelNodes);
				curlevel++;//当前层要加一层
				curlevelNodes=0;//清空
			}
			if(cur.left!=null){
				levelmap.put(cur.left, curNodelevel+1);//上一个节点的下一层
				queue.add(cur.left);
			}if (cur.right!=null){
				levelmap.put(cur.right,curNodelevel+1);//记录节点所在层数
				queue.add(cur.right);
			}
			// 
			System.out.print(cur.value);
			if(cur.left!=null){//先放左
				queue.add(cur.left);
			}if (cur.right!=null){//后放右
				queue.add(cur.right);
			}
		}
	}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值