顺序存储二叉树前中后序遍历(java)

本文介绍了顺序二叉树的概念,特别关注其在完全二叉树结构下的特性,展示了如何根据给定数组构建顺序二叉树,并提供了前序、中序和后序遍历的示例代码。通过这个例子,读者可以理解如何利用递归实现二叉树的遍历算法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

顺序二叉树只考虑完全二叉树

第n个元素的左子节点:2*n+1

第n个元素的右子节点:2*n+2

n为二叉树中的第几个元素(从0开始编号)

eg:数组为{1,2,3,4,5,6,7}

二叉树图为:

 

package tree;

public class ArrBinaryTreeAPP {

	public static void main(String[] args) {
		// TODO 自动生成的方法存根
		int[] arr={1,2,3,4,5,6,7};
		ArrBinaryTree arrBinaryTree=new ArrBinaryTree(arr);
		System.out.println("顺序存储二叉树前序遍历:");
		arrBinaryTree.preOrder(0);
		System.out.println("\n顺序存储二叉树中序遍历:");
		arrBinaryTree.midOrder(0);
		System.out.println("\n顺序存储二叉树后序遍历:");
		arrBinaryTree.postOrder(0);
	}
	
}
class ArrBinaryTree{
	private int[] arr;
	public ArrBinaryTree(int[] arr) {
		this.arr=arr;
	}
	
	//前序遍历
	public void preOrder(int index) {
		if(arr.length==0||arr==null) {
			System.out.println("数列为空");
			return;
		}
		System.out.printf(arr[index]+" ");
		if((index*2+1)<arr.length) {
			preOrder(index*2+1);
		}
		if((index*2+2)<arr.length) {
			preOrder(index*2+2);
		}
	}
	//中序遍历
	public void midOrder(int index) {
		if(arr.length==0||arr==null) {
			System.out.println("数列为空");
			return;
		}
		if((index*2+1)<arr.length) {
			midOrder(index*2+1);
		}
		System.out.printf(arr[index]+" ");
		if((index*2+2)<arr.length) {
			midOrder(index*2+2);
		}
	}
	
	//后序遍历
	public void postOrder(int index) {
		if(arr.length==0||arr==null) {
			System.out.println("数列为空");
			return;
		}
		if((index*2+1)<arr.length) {
			postOrder(index*2+1);
		}
		if((index*2+2)<arr.length) {
			postOrder(index*2+2);
		}
		System.out.printf(arr[index]+" ");
	}
}

运行结果:

 

### 二叉树序、中序和后序遍历的非递归实现 对于二叉树序、中序以及后序遍历,其主要区别在于访问节点相对于处理左右子树的位置不同。为了实现这些遍历方式的非递归版本,通常会采用栈来模拟递归调用的行为。 #### 遍历 (Pre-order Traversal)遍历中,首先访问根节点,接着依次访问左子树和右子树。下面是一个基于栈的数据结构用于存储待处理节点的方法: ```java public void preOrderTraversal(TreeNode root) { Stack<TreeNode> stack = new Stack<>(); while (!stack.isEmpty() || root != null) { if (root != null) { System.out.print(root.val + " "); // 访问当节点 stack.push(root); root = root.left; // 移动到左侧孩子 } else { TreeNode node = stack.pop(); root = node.right; // 转向右侧孩子继续探索 } } } ``` 此代码片段展示了如何通过显式管理一个外部栈来进行遍历[^1]。 #### 中序遍历 (In-order Traversal) 当中序遍历时,遵循的是先访问最左边的孩子直到叶子节点,再回溯并打印父节点最后才去右边分支的原则。这里同样可以利用栈帮助完成这一过程: ```c void inorderNonRecursive(struct Node* root){ struct Node *nodeStack[MAX]; int top=-1; struct Node *current=root; while(current!=NULL||top!=-1){ /* Reach the left most Node of the current Node */ while (current != NULL){ push(nodeStack, &top, current); // Push to stack until it reaches end. current=current->left; } /* Current must be NULL at this point */ if(top!=-1){ current=pop(nodeStack,&top); // Backtrack from empty subtree and visit parent node. printf("%d ",current->data); /* We have visited the node and its left subtree. Now, it's right subtree's turn */ current=current->right; } } } ``` 上述实现了使用C语言编写的中序遍历逻辑[^2]. #### 后序遍历 (Post-order Traversal) 相较于其他两种顺序来说,后序遍历更为复杂一些因为它需要确保每次返回上层时都能正确判断是否应该输出该层上的元素还是进一步深入下一层。一种常见的做法是在第二次遇到某个顶点时才真正对其进行操作: ```cpp struct TreeLinkNode{ int val; TreeLinkNode *left,*right; }; vector<int> postorderTraversal(TreeLinkNode *root) { vector<int> res; if(!root)return res; unordered_map<TreeLinkNode*,int> m; stack<TreeLinkNode*> s({root}); while(!s.empty()){ auto t=s.top();s.pop(); if(t->left&&m[t]!=2){ s.push(t); s.push(t->left); continue; } if(t->right&&!t->right->val==INT_MIN){ s.push(t); s.push(t->right); m[t]=2; continue; } res.push_back(t->val); t->val=INT_MIN;// mark as visited } return res; } ``` 这段伪码提供了一种解决策略,在实际应用中可能还需要调整以适应特定编程环境的要求[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值