二叉树构建以及前中后序遍历(递归和非递归)Java实现

来源:互联网 发布:c语言波兰表达式 编辑:程序博客网 时间:2024/04/29 11:53
/*
 * 左右子树的引用
 * 存储的数据(此处使用整型)
 * 使用私有变量较麻烦,因此使用public 
 */
public class Node {
public int data;
public Node leftChild;
public Node rightChild;
public int flag;
public Node(int data)
{
this.data = data;
leftChild = null;
rightChild = null;
}

}


import java.util.Scanner;
import java.util.Stack;


/*
 * 树中保存的是根节点
 */


public class BiTree {
public Node root;
public BiTree()
{
root = createTree();
}

//建树
public Node createTree()
{
Node node = null;
Scanner in = new Scanner(System.in);
int data = in.nextInt();
if(data == -1)//此处使用负数代表停止
node = null;
else
{
node = new Node(data);
node.leftChild = createTree();
node.rightChild = createTree();
}
return node;
}

//前序遍历
public void pre(Node node)
{
if(node == null)
return;
else
{
System.out.print(node.data+" ");
pre(node.leftChild);
pre(node.rightChild);
}
}
//中序遍历
public void med(Node node)
{
if(node == null)
return;
else
{
pre(node.leftChild);
System.out.print(node.data+" ");
pre(node.rightChild);
}
}
//后续遍历
public void last(Node node)
{
if(node == null)
return;
else
{
pre(node.leftChild);
pre(node.rightChild);
System.out.print(node.data+" ");
}
}

/*
* 前序遍历非递归算法

* 根左右
* 从左子树回来的时候需要用到右子树,因此需要讲根节点进行压栈处理

*/
public void nonPre()
{
Stack<Node> sNode = new Stack<Node>();
if(root==null)
{
return;
}
Node node = root;
while(!sNode.isEmpty() || node!=null)
{
//左子树
while(node!=null)
{
System.out.print(node.data+" ");
sNode.push(node);//入栈
node = node.leftChild;//进入左子树
}

//出栈拿着这个节点继续左子树右子树
if(!sNode.isEmpty())
{
node = sNode.pop().rightChild;
}
}
}

/*
* 中遍历非递归算法
*/
public void nonMed()
{
Stack<Node> sNode = new Stack<Node>();
if(root==null)
{
return;
}
Node node = root;
while(!sNode.isEmpty() || node!=null)
{
//左子树
while(node!=null)
{
sNode.push(node);//入栈
node = node.leftChild;//进入左子树
}

//出栈拿着这个节点继续左子树右子树
if(!sNode.isEmpty())
{
node = sNode.pop();
System.out.print(node.data+" ");
node = node.rightChild;
}
}
}
/*
* 后序遍历非递归算法
* 看完了,在看时从栈里面出来的时候就是输出的时候
* 因此需要看两遍
* 先立一个flag标志看了几次了

* 先遍历所有的左子树,然后看一下最近的栈里面的元素进行右子树的遍历
* 右子树之后又回到了左子树右子树的情况中递归了开始
* 左子树想进入右子树必须先被看一眼,
* 看了一样之后,如果你想处于站的最顶端才能被输出,此时 一定是自己的右子树被全部遍历
* 完成之后
*/
public void nonLast()
{
Stack<Node> stack = new Stack<Node>();
Node node = root;
if(node == null)
{
System.out.println();
}
while(!stack.isEmpty() || node!=null)
{
//左子树入栈
while(node!=null)
{
node.flag = 2;//给你两次机会
stack.push(node);
node = node.leftChild;
}



//被看完了的直接输出
while(!stack.isEmpty() && stack.peek().flag==1)
{
node = stack.pop();
System.out.print(node + " ");
}


//左边的路走不通了看看栈中的数据走右边
if(!stack.isEmpty())
{
node = stack.peek();
node.flag = 1;//看过了
node = node.rightChild;
}


import java.util.Scanner;


public class Main {


public static void main(String[] args) {
// TODO Auto-generated method stub
BiTree bt = new BiTree();//新建一个数
System.out.print("前序遍历:");
bt.pre(bt.root);
System.out.println();
System.out.print("中序遍历:");
bt.med(bt.root);
System.out.println();
System.out.print("后序遍历:");
bt.last(bt.root);
System.out.println();
bt.nonPre();
System.out.println();
bt.nonMed();
}
}

}
}


}

0 0
原创粉丝点击