快速掌握二叉树的7种遍历方式哦!!!

Posted SSimeng

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了快速掌握二叉树的7种遍历方式哦!!!相关的知识,希望对你有一定的参考价值。

1. 树节点结构的定义

树是由一个个节点组成的结构,有个特殊的结点是根节点,而每个结点由自己的左孩子结点右孩子结点组成。

树的结构图:
在这里插入图片描述
接下来是对树中节点的定义:

/**
 * 树节点结构的定义
 * @author Simeng
 *
 */
public class TreeNode {
	private int data;//数据域
	private TreeNode left;//左子结点
	private TreeNode right;//右节点
	public TreeNode(int data, TreeNode left, TreeNode right) {
		this.data = data;
		this.left = left;
		this.right = right;
	}
	@Override
	public String toString() {
		return "TreeNode [data=" + data + ", left=" + left + ", right=" + right + "]";
	}
	

}

2. 树的创建

有了节点,我们就要拼凑,定义方法去构建一棵二叉树。
(1)树的定义:

/**
 * 定义树的结构
 * @author 司蒙
 *
 */
public class Tree {
	private TreeNode root;//树的根节点
	private int size;//树的节点的个数
	
	public TreeNode getRoot() {
		return root;
	}
}

(2)树的创建
在这里插入图片描述

/**
	 * 构建一棵二叉树,返回树的根节点
	 */
	public void buildTree(int data) {
		if (root == null) {
			 root = new TreeNode(data);// 当为空树时,直接将data封装成一个node对象,赋值给root,作为树的根节点
		}else {
			// 不为空
			TreeNode currentNode = root;
			while(true) {
				if (data < currentNode.data) {// 在左子树这边
					if (currentNode.left == null) {
						currentNode.left = new TreeNode(data);// 如果子节点为空,直接将新的节点挂到上面去即可						
						return;
					} else {
						currentNode = currentNode.left;
					}
				}else {//data>currentNode.data,在右子树这边添加
					if (currentNode.right == null) {
						currentNode.right = new TreeNode(data);// 如果子节点为空,直接将新的节点挂到上面去即可
						return;
					} else {
						currentNode = currentNode.right;
					}
					
				}
			}
		}
		this.size++;//添加后,节点个数要增加
	}
public class TestTree {
	public static void main(String[] args) {
		Tree t=new Tree();//构建树
		t.buildTree(8);
		t.buildTree(5);
		t.buildTree(3);
		t.buildTree(4);
		t.buildTree(17);
	}
}

3. 树的深度优先遍历

3.1 树的前序遍历【根左右】(递归和非递归)

①递归做法

/**
	 * 二叉树的前序遍历(递归)
	 * 
	 * @param root
	 */
	public void preOrder1(TreeNode root) {
		if (root == null)
			return;
		System.out.print(root.data + " ");
		preOrder1(root.left);
		preOrder1(root.right);

	}

②迭代做法

/**
	 * 二叉树的前序遍历(迭代)
	 * @param root
	 */
	public void preOrder2(TreeNode root) {
		Stack<TreeNode> stack=new Stack<TreeNode>();
		TreeNode currNode=root;
		if(currNode!=null) {
			stack.push(currNode);//将根节点入栈
			while(!stack.isEmpty()) {
				currNode=stack.pop();
				System.out.println(currNode.data+" ");
				if(currNode.right!=null) {
					stack.push(currNode.right);//由于栈结构,先压右节点
				}
				if(currNode.left!=null) {
					stack.push(currNode.left);
				}
			}
		}
	}

前序遍历测试


public class TestTree {
	public static void main(String[] args) {
		Tree t=new Tree();//构建树
		t.buildTree(8);
		t.buildTree(5);
		t.buildTree(3);
		t.buildTree(4);
		t.buildTree(17);
		System.out.print("树的前序遍历(递归)为:[");
		t.preOrder1(t.getRoot());
		System.out.println("]");
		
		System.out.print("树的前序遍历(迭代)为:[");
		t.preOrder2(t.getRoot());
		System.out.println("]");
	}
}

在这里插入图片描述

3.2 树的中序遍历【左根右】(递归和非递归)

①递归

/**
	 * 二叉树的中序遍历(递归)
	 * 
	 * @param root
	 */
	public void inOrder1(TreeNode root) {
		if (root == null)
			return;
		inOrder1(root.left);
		System.out.print(root.data + " ");
		inOrder2(root.right);
	}
	

②迭代

/**
	 * 二叉树的中序遍历(迭代)
	 * 
	 * @param root
	 */
	public void inOrder2(TreeNode root) {
		Stack<TreeNode> stack = new Stack<TreeNode>();
		TreeNode currNode=root;
		while(currNode !=null || !stack.isEmpty()) {
			
			while(currNode!=null) {
				stack.push(currNode);
				currNode=currNode.left;
			}
			if(!stack.isEmpty()) {
				currNode=stack.pop();//弹出左结点
				System.out.print(currNode.data+" ");
				currNode=currNode.right;
			}
		}

	}

中序遍历测试:

        System.out.print("树的中序遍历(递归)为:[");
		t.inOrder1(t.getRoot());
		System.out.println("]");
		
		System.out.print("树的中序遍历(递归)为:[");
		t.inOrder2(t.getRoot());
		System.out.println("]");

中序测试结果:
在这里插入图片描述

3.3 树的后序遍历【左右根】(递归和非递归)

①递归

/**
	 * 二叉树的后序遍历(递归)
	 * 
	 * @param root
	 */
	public void afterOrder1(TreeNode root) {
		if (root == null)
			return;
		afterOrder1(root.left);
		afterOrder1(root.right);
		System.out.print(root.data + " ");
	}

②迭代

/**
	 * 二叉树的后序遍历(迭代)
	 * 
	 * @param root
	 */
	public void afterOrder2(TreeNode root) {
		Stack<TreeNode> stack = new Stack<TreeNode>();
		Stack<TreeNode> stack2=new Stack<TreeNode>();
		TreeNode curNode=root;
		while(curNode!=null || !stack.isEmpty()) {
			while(curNode!=null) {
				stack.push(curNode);
				stack2.push(curNode);
				curNode=curNode.right;
			}
			if(!stack.isEmpty()) {
				curNode=stack.pop();
				curNode=curNode.left;
			}
		}
		while(!stack2.isEmpty()) {
			curNode=stack2.pop();
			System.out.print(curNode.data+" ");
		}
	}

树的后续遍历测试结果:
在这里插入图片描述

4. 树的广度优先遍历(层序遍历)

/**
	 * 树的层序遍历
	 * @param root
	 */
	public void widthOrder(TreeNode root) {
		if(root==null) return;
		Queue<TreeNode> q=new LinkedList<TreeNode>();
		TreeNode curNode=root;
		q.offer(curNode);
		while(!q.isEmpty()) {
			curNode=q.poll();
			System.out.print(curNode.data+" ");
			if(curNode.left!=null) {
				q.offer(curNode.left);
			}
			if(curNode.right!=null) {
				q.offer(curNode.right);
			}
		}
	}

层序遍历测试:
在这里插入图片描述
本次二叉树的遍历就到此结束了,如有问题请指正谢谢!!!

以上是关于快速掌握二叉树的7种遍历方式哦!!!的主要内容,如果未能解决你的问题,请参考以下文章

算法总结你真的掌握了二叉树的遍历嘛

二叉树需要掌握的基本知识

必须掌握,二叉树的前中后序遍历(迭代+递归)详细代码与思路

数据结构-遍历序列求二叉树

数据结构Java版之遍历二叉树

数据结构二叉树的基础操作( 1.创建二叉树2.先序遍历3.中序排序4.后序遍历 5.层序遍历6. 统计节点的数目 7.交换左右子树 8.计算并输出该二叉树的深度)