二叉树的遍历
总体来说分为递归和非递归实现
- 前序遍历
- 循环前序遍历
/**
*二叉树前序遍历DLR
*/
public static void preOrder(TreeNode rootNode) {
if (rootNode != null) {
System.out.println(rootNode.getData());
preOrder(rootNode.getLeftNode());
preOrder(rootNode.getRightNode());
}
}
- 非递归实现
/**
* 前序非递归实现,借助栈,先进后出
*
* @param
*/
public static void preOrderNonRecursive(TreeNode root) {
if (root == null) {
return;
}
//栈
Stack<TreeNode> S = new Stack<>();
//
while (true) {
while (root != null) {
System.out.println(root.getData());
S.push(root);
root = root.getLeftNode();
}
if (S.isEmpty()) {
break;
}
root = S.pop();
root = root.getRightNode();
}
}
- 中序遍历
- 递归实现
/**
* 中序遍历
*/
public void inOrder(TreeNode root) {
if (root != null) {
inOrder(root.getLeftNode()); //LDR
System.out.println(root.getData());
inOrder(root.getRightNode());
}
}`
- 非递归实现
/**
* 二叉树中序遍历
*
* @param root
*/
public void inOrderNonRecursive(TreeNode root) {
if (root == null) {
return;
}
/**
* 靠栈实现
*/
Stack<TreeNode> S = new Stack<>();
while (true) {
while (root != null) {
//将节点进栈
S.push(root);
root = root.getLeftNode();
}
if (S.isEmpty()) {
break;
}
System.out.println(root.getData());
//出栈,操作右节点
root = S.pop();
root = root.getRightNode();
}
}
- 后序遍历’
后序遍历的实现相对复杂一点。 后序遍历中的每个节点需要访问两次:1.左子树遍历的时候需要访问一次,2遍历右子树的时候需要访问一次。所以在进行数据节点访问的时候要考虑到底是遍历左子树的返回还是右子树的返回。
判断:
当出栈的节点,和栈顶元素的右节点作比较,相同则已经完成了左右子树的遍历,直接输出栈定元素即可。
非递归实现后序遍历
/**
* 后序遍历非递归实现
*
* @param root
*/
public void PostOrderNonRecursive(TreeNode root) {
/**
* 根节点不为空
*/
if (root == null)
return;
/**
* 根节点不为空,借助栈后进先出实现操作
*/
Stack<TreeNode> S = new Stack<>();
while (true) {
if (root != null) { //1.不断深入左子树,并进行左节点入栈操作
S.push(root);
root = root.getLeftNode();
} else {
/**
* 弹栈的节点如果与栈顶右节点相同,完成了两次遍历操作,就输出该栈顶元素元素
*/
if (S.isEmpty()) {
break;
}
/**
* 进行节点遍历输出
*/
if (S.peek().getRightNode() == null) {
root = S.pop();
System.out.println(root.getData());
/**
* 判断出栈的节点是否已经完成两次节点的访问:
*/
if (root == S.peek().getRightNode()) {
System.out.println(S.peek().getData());
S.pop();
}
if (!S.isEmpty()) {
root=S.peek().getRightNode();
}
}
}
}
}