左神数据结构与算法笔记-----二叉树(一)

二叉树


一、概念及结构

一棵二叉树是结点的一个有限集合,该集合或者为空,或者是由一个根节点加上两棵别称为左子树和右子树的二叉树组成。

二叉树的特点
1、每个结点最多有两棵子树,即二叉树不存在度大于2的结点。
2、二叉树的子树有左右之分,其子树的次序不能颠倒。

结构:

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

二、二叉树三种遍历方法

1、定义

请添加图片描述

2、举例

假设一个二叉树如图:
请添加图片描述
先序遍历(头左右):1245367
中序遍历(左头右):4251637
后序遍历(左右头):4526731

3、代码(递归方法)

//前序遍历
public static void pre(Node head) {
		if(head==null) {
			return;
		}
		System.out.print(head.value+" ");
		pre(head.left);
		pre(head.right);
	}

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

4.原理解析

假设有个递归函数:

public static void f(Node head) {
		if(head==null) {
			return;
		}
		//1
		f(head.left);
		//2
		f(head.right);
		//3
}

//1:第一次来到节点
//2:第二次来到节点
//3:第三次来到节点

对于上述的二叉树有这么一个递归序:

请添加图片描述
通过观察我们发现,先序遍历是第一次访问节点时对该节点的操作,中序遍历是第二次访问节点时对该节点的操作,后序遍历是第三次访问节点时对该节点的操作。

5.非递归方法

非递归方法需要用到栈。
我们直接上代码:

//先序遍历(非递归)
	public static void pre(Node head) {
		if(head==null) {
			return;
		}
		Stack<Node> stack=new Stack<>();
		stack.push(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 static void in(Node head) {
		if(head==null) {
			return;
		}
		Stack<Node> stack=new Stack<>();
		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;
			}
		}
	}
	
	//后序遍历(非递归)
	public static void pos(Node head) {
		if(head==null) {
			return;
		}
		Stack<Node> stack=new Stack<>();
		stack.push(head);
		Node h=head;
		Node c=null;
		while(!stack.isEmpty()) {
			c=stack.peek();
			if(c.left!=null&&h!=c.right&&h!=c.left) {	//h!=c.right连右节点都遍历了,左节点肯定遍历了
				stack.push(c.left);
			}else if(c.right!=null&&h!=c.right) {
				stack.push(c.right);
			}else {
				System.out.print(stack.pop().value+" ");
				h=c;
			}
		}
	}

三、二叉树的层序遍历

层序遍历即把二叉树从上到下按每层的顺序,从左往右遍历。
这里需要用到队列。
代码如下:

public static void level(Node head) {
		if(head==null) {
			return;
		}
		Queue<Node> queue=new LinkedList<>();
		queue.offer(head);
		while(!queue.isEmpty()) {
			int curNum=queue.size();	//此时队列中只存了当前层的节点
			for(int i=0;i<curNum;i++) {	
				Node curNode=queue.poll();
				if(curNode.left!=null) {
					queue.offer(curNode.left);
				}
				if(curNode.right!=null) {
					queue.offer(curNode.right);
				}
			}
		}
	}

四、总结

我在刚接触函数递归的时候懵懵懂懂,当深入学习二叉树时才明白递归的套路。
三种遍历方式是以后学习树形dp的基础,因此务必将这三种递归套路熟悉。

参考博文:https://blog.csdn.net/weixin_45796387/article/details/114994648

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值