基于Java实现二叉树的三种遍历每,每种遍历都采用递归和循环两种方式实现

使用Java语言实现二叉树的生成

//arrs为放入到树节点的数据,demo中将int类型的数据置入节点中
public List<TreeNode> initTree(int[] arrs) {
		List<TreeNode> nodes = new ArrayList<TreeNode>();
		for (int data : arrs) {
			nodes.add(new TreeNode(data));
		}
		//此处每个父节点的index < (arrs.length / 2 - 1)是确保每个父节点的左右子节点都存在 
		for (int parentIndex = 0; parentIndex < arrs.length / 2 - 1; parentIndex++) {
			nodes.get(parentIndex).leftNode = nodes.get(parentIndex * 2 + 1);
			nodes.get(parentIndex).rightNode = nodes.get(parentIndex * 2 + 2); 
		}
		//(arrs.length / 2 - 1)最后一个父节点,通过二叉树的定义可知		
                int lastParentIndex = arrs.length / 2 - 1;
		nodes.get(lastParentIndex).leftNode = nodes.get(lastParentIndex * 2 + 1);
		//arrs.length % 2 != 0,作为判断最后一个父节点的右子节点是否存在的判断条件		
                if(arrs.length % 2 != 0){
			nodes.get(lastParentIndex).rightNode = nodes.get(lastParentIndex * 2 + 2);
		}
		return nodes;
}

三种遍历方式

(1). 先序遍历
(2). 中序遍历
(3). 后序遍历
三种遍历方式,也就是遍历的顺序不一样。
先序遍历: “根左右”,遍历的顺序: 根节点->左节点->右节点。
中序遍历: “左根右”,遍历的顺序: 左节点->根节点->右节点。
后序遍历: “左右根”,遍历的顺序: 左节点->右节点->根节点。

先序遍历

使用递归

/*
	 * 先序遍历二叉树: 根左右
	 * 
	 * @param node
	 *       遍历的节点
	 * */
	public void preOrderTraverse(TreeNode node){
		if(node == null)
			return;
		System.out.print(node.data + " "); //第一次进来是rootNode
		preOrderTraverse(node.leftNode);  //递归输出左节点		
                preOrderTraverse(node.rightNode); //递归输出右节点
	}

使用循环

	/*
	 * 先序遍历二叉树: 根左右
	 * 
	 * 使用循环
	 * 
	 * @param node
	 *       遍历的节点
	 * */
	public void preOrderTraverseByWhile(TreeNode node){
		LinkedList<TreeNode> stack = new LinkedList<TreeNode>();
		stack.push(node);
		TreeNode currentNode;
		while (!stack.isEmpty()) {
			currentNode = stack.pop();
			System.out.print(currentNode.data + " ");
			if(currentNode.rightNode != null){
				stack.push(currentNode.rightNode);
			}
			if (currentNode.leftNode != null) {
				stack.push(currentNode.leftNode);
			}
		}
	}

中序遍历

使用递归

	/*
	 * 中序遍历二叉树: 左根右
	 * 
	 * @param node
	 *       遍历的节点
	 * */
	public void inOrderTraverse(TreeNode node){
		if(node == null)
			return;
		inOrderTraverse(node.leftNode); //递归输出左节点
		System.out.print(node.data + " "); 
		inOrderTraverse(node.rightNode); //递归输出右节点
	}

使用循环

	/*
	 * 中序遍历二叉树: 左根右
	 * 
	 * 使用循环
	 * 
	 * @param node
	 *       遍历的节点
	 * */
	public void inOrderTraverseByWhile(TreeNode node){
		LinkedList<TreeNode> stack = new LinkedList<TreeNode>();
		TreeNode currentNode = node;
		while (currentNode != null || !stack.isEmpty()) {
			while(currentNode != null){
				stack.push(currentNode);
				currentNode = currentNode.leftNode;
			}
			if(!stack.isEmpty()){
				currentNode = stack.pop();
				System.out.print(currentNode.data + "");
				currentNode = currentNode.rightNode;
			}
		}
	}

后序遍历

使用递归

	/*
	 * 后序遍历二叉树: 左右根
	 * 
	 * @param node
	 *       遍历的节点
	 * */
	public void afterOrderTraverse(TreeNode node){
		if(node == null)
			return;
		afterOrderTraverse(node.leftNode);//递归输出左节点
		afterOrderTraverse(node.rightNode);//递归输出右节点
		System.out.print(node.data + " ");
	}

使用循环

	/*
	 * 后序遍历二叉树: 左右根
	 * 
	 *  使用循环
	 * 
	 * @param node
	 *       遍历的节点
	 * */
	public void afterOrderTraverseByWhile(TreeNode node){
		LinkedList<TreeNode> stack = new LinkedList<TreeNode>();
		TreeNode rightNode = null;
		TreeNode currentNode = node;
		while (currentNode != null || !stack.isEmpty()) {
			while(currentNode != null){
				stack.push(currentNode);
				currentNode = currentNode.leftNode;
			}
			currentNode = stack.pop();
			//当上一个访问的结点是右孩子或者当前结点没有右孩子则访问当前结点
			while(currentNode != null && (currentNode.rightNode == null || currentNode.rightNode == rightNode)){
				System.out.print(currentNode.data + " ");
				rightNode = currentNode;
				if(stack.isEmpty()){
					return;
				}
				currentNode = stack.pop();
			}
			stack.push(currentNode);
			currentNode = currentNode.rightNode;
		}
	}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

byg_qlh

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值