二叉树遍历

二叉树

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

遍历二叉树代码,递归序情况下一个节点可能会遍历到三次,但什么都没干。

public static void f(Node head){
	//1.如果为空则返回
	if(head ==null){
		return;
	}
	//2.遍历左子树
	f(head.left);
	//3.遍历右子树
	f(head.right);
}

在这里插入图片描述

递归序:1-2-4-4-4-2-5-5-5-2-1-3-6-6-6-3-7-7-7-3-1

先序遍历(第一次遇到节点就打印):头-左子树-右子树 1-2-4-5-3-6-7

中序遍历(第二次来到节点的时候才打印):左子树-头-右子树 4-2-5-1-6-3-7

后序遍历(第三次遇到节点才打印):左子树-右子树-头 4-5-2-6-7-3-1

先序遍历

1)从栈中弹出一个节点car

2)打印处理car

3)先压右节点入栈再压左节点入栈(如果有的话)

4)重复 1)

public static void preOrderUnRecur(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();
}
后序遍历

申请两个栈,另一个是收集栈

1)从栈中弹出一个节点car

2)把car放入收集栈

3)先压左再压右

4)重复1

5)收集栈弹出的顺序就是后序遍历的顺序

public static void posOrderUnRecur1(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();
}
中序遍历

每棵子树整棵树左边界进栈,依次弹出的过程中打印,对弹出节点的右树重复

1)压入头结点,压入栈

2)找到节点的左子树弹入栈并重复到没有左子树

3)若没有右树则弹出并打印,若有,弹出打印后则对右树进行1)操作

public static void inOrderUnRecur(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=stack.pop();//弹出就打印
				System.out.print(head.value+" ");
				head = head.right;//找右子树
			}
		}
	}
	System.out.println();
}
深度优先遍历=先序遍历
宽度优先遍历

宽度优先遍历用队列,头部进尾部出

弹出时先放左节点再放右节点,弹出时打印

public static void w(Node head){
	if(head==null){
		return ;
	}
	Queue<Node> queue = new LinkList<>();
	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);//当前节点所在的层数
		if(curNodeLevel == curLevel){//当前层和想统计的层相同时
			curLevelNodes++;
		}else{//到了下一层,要结算
			max = Math.max(max,curLevelNodes);
			curLevel++;
			curLevelNodes = 1;
		}
		System.out.println(cur.value);
		if(cur.left != null){
			levelMap.put(cur.left,curLevel+1);
			queue.add(cur.left);
		}
		if(cur.right != null){
			levelMap.put(cur.left,curLevel+1);
			queue.add(cur.right);
		}
	}
  • 14
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值