您的位置:首页 > 编程语言 > Java开发

Java二叉树的递归,非递归遍历,高度,节点数,叶子节点数

2016-05-17 19:37 495 查看
import java.util.LinkedList;
import java.util.Queue;
import java.util.Stack;

public class Main {
public static class TreeNode<T>{
T data;
TreeNode<T> left=null;
TreeNode<T> right=null;

public TreeNode() {}
public TreeNode(T data){
this.data=data;
}
public TreeNode(T data, TreeNode left, TreeNode right) {
super();
this.data = data;
this.left = left;
this.right = right;
}
}

public static class BinaryTree<T>{
/**二叉树的根节点*/
private TreeNode<T> root;

public BinaryTree(){}
public BinaryTree(TreeNode<T> root){
this.root = root;
}

/* public TreeNode<Integer> createBinaryTree(){
TreeNode<Integer> e = new   TreeNode<Integer>(5);
TreeNode<Integer> g = new   TreeNode<Integer>(7);
TreeNode<Integer> h = new   TreeNode<Integer>(8);

TreeNode<Integer> l = new   TreeNode<Integer>(12);
TreeNode<Integer> m = new   TreeNode<Integer>(13);
TreeNode<Integer> n = new   TreeNode<Integer>(14);
TreeNode<Integer> k = new   TreeNode<Integer>(11, n, null);
TreeNode<Integer> j = new   TreeNode<Integer>(10, l, m);
TreeNode<Integer> i = new   TreeNode<Integer>(9, j, k);
TreeNode<Integer> d = new   TreeNode<Integer>(4, null, g);

TreeNode<Integer> f = new   TreeNode<Integer>(6, h, i);
TreeNode<Integer> b = new   TreeNode<Integer>(2, d, e);
TreeNode<Integer> c = new   TreeNode<Integer>(3, f, null);

TreeNode<Integer> root = new   TreeNode<Integer>(1, b, c);
return root;
}*/
//递归前序
public void preOrder(TreeNode<T> root){
if(root!=null){
visit(root);
preOrder(root.left);
preOrder(root.right);
}
}
/*非递归前序:对于任一结点P:

1)访问结点P,并将结点P入栈;

2)判断结点P的左孩子是否为空,若为空,则取栈顶结点并进行出栈操作,并将栈顶结点的右孩子置为当前的结点P,循环至1);若不为空,则将P的左孩子置为当前的结点P;

3)直到P为NULL并且栈为空,则遍历结束。
*/
public void nonRecursivePreOrder(TreeNode<T> root){
Stack<TreeNode<T>> s=new Stack<TreeNode<T>>();
if(root!=null){
s.push(root);//先把根节点入栈
while(!s.isEmpty()){//while栈不为空
TreeNode<T> node=s.pop();//弹出栈
visit(node);
if(node.right!=null) s.push(node.right);//把右节点入栈
if(node.left!=null)  s.push(node.left); //把左节点入栈
}

}
}

//递归中序
public void inOrder(TreeNode<T> root){
if(root!=null){

inOrder(root.left);
visit(root);
inOrder(root.right);
}
}
//非递归中序遍历:对于任一结点P,将其入栈,然后沿其左子树一直往下搜索,直到搜索到没有左孩子的结点,此时该结点出现在栈顶,
//但是此时不能将其出栈并访问,因此其右孩子还为被访问。所以接下来按照相同的规则对其右子树进行相同的处理,当访问完其右孩子时,该结点又出现在栈顶,此时可以将其出栈并访问。
public void nonRecursiveInOrder(TreeNode<T> root){
Stack<TreeNode<T>> stack=new Stack<TreeNode<T>>();
TreeNode<T> node=root;
while(node!=null||!stack.isEmpty()){
//左子树一直入栈
while(node!=null){//一直找到节点左子树是空的节点
stack.push(node);
node=node.left;
}

node=stack.pop();//左子树是空的就是访问这个节点
visit(node);
node=node.right;//在找该节点的右子树
}
}
//递归后序
public void postOrder(TreeNode<T> root){
if(root!=null){
postOrder(root.left);
postOrder(root.right);
visit(root);
}
}
//非递归后序遍历
public void nonRecursivePostOrder(TreeNode<T> root){
TreeNode<T> node=root;
TreeNode<T> preNode=null;//记录之前遍历的右结点
Stack<TreeNode<T>> stack=new Stack<TreeNode<T>>();
while(node!=null||!stack.isEmpty()){
/*左子树一直入栈*/
while(node!=null){
stack.push(node);
node=node.left;
}
node=stack.peek();//获得栈顶节点但不出栈

/*如果右结点为空,或者右结点之前遍历过,打印根结点*/
if(node.right==null||node.right==preNode){
visit(node);
node=stack.pop();
preNode = node;
node=null;
}
else{
node=node.right;
}

}

}
//层次遍历
public void levelTraverse(TreeNode<T> root){
//Queue是一个接口,不能直接实例化,一般使用它的实现类LinkedList当做队列用,
//Queue的实现类还有LinkedList, PriorityQueue, LinkedBlockingQueue, BlockingQueue, ArrayBlockingQueue, LinkedBlockingQueue, PriorityBlockingQueue
Queue<TreeNode<T>> queue=new LinkedList<TreeNode<T>>();
TreeNode<T> node=root;
queue.offer(node);//队列用offer添加元素

/*对每一个节点先出队列再让其左节点和右节点入队列*/
while(!queue.isEmpty()){
node=queue.poll();//队列用poll出队列
if(node!=null){
visit(node);
//左右节点入队列
queue.offer(node.left);
queue.offer(node.right);
}

}
}
//递归求树的高度
public int treeHeight(TreeNode<T> root){
if(root==null){
return 0;
}
else{
int leftTreeHeight=treeHeight(root.left);
int rightTreeHeight=treeHeight(root.right);
return leftTreeHeight>rightTreeHeight?leftTreeHeight+1:rightTreeHeight+1;
}
}
//递归求节点总数
public int treeNodes(TreeNode<T> root){
if(root==null){
return 0;
}
else{
int leftTreeNodes=treeNodes(root.left);
int rightTreeNodes=treeNodes(root.right);
return leftTreeNodes+rightTreeNodes+1;
}
}
//递归求叶子节点总数
public int treeLeaf(TreeNode<T> root){
if(root==null){
return 0;
}
else{
int leftTreeLeaf=treeLeaf(root.left);
int rightTreeLeaf=treeLeaf(root.right);
if(root.left==null&&root.right==null){
return leftTreeLeaf+rightTreeLeaf+1;
}
else{
return leftTreeLeaf+rightTreeLeaf;
}
}
}
public void visit(TreeNode<T> root) {
System.out.print(root.data+" ");
}

}

public static void main(String[] args) {
TreeNode<Integer> e = new   TreeNode<Integer>(5);
TreeNode<Integer> g = new   TreeNode<Integer>(7);
TreeNode<Integer> h = new   TreeNode<Integer>(8);

TreeNode<Integer> l = new   TreeNode<Integer>(12);
TreeNode<Integer> m = new   TreeNode<Integer>(13);
TreeNode<Integer> n = new   TreeNode<Integer>(14);
TreeNode<Integer> k = new   TreeNode<Integer>(11, n, null);
TreeNode<Integer> j = new   TreeNode<Integer>(10, l, m);
TreeNode<Integer> i = new   TreeNode<Integer>(9, j, k);
TreeNode<Integer> d = new   TreeNode<Integer>(4, null, g);

TreeNode<Integer> f = new   TreeNode<Integer>(6, h, i);
TreeNode<Integer> b = new   TreeNode<Integer>(2, d, e);
TreeNode<Integer> c = new   TreeNode<Integer>(3, f, null);

TreeNode<Integer> root = new   TreeNode<Integer>(1, b, c);

BinaryTree<Integer> tree=new BinaryTree<Integer>(root);
System.out.println("递归前序遍历二叉树结果:");
tree.preOrder(root);
System.out.println();
System.out.println("非递归前序遍历二叉树结果:");
tree.nonRecursivePreOrder(root);
System.out.println();

System.out.println("递归中序遍历二叉树结果:");
tree.inOrder(root);
System.out.println();
System.out.println("非递归中序遍历二叉树结果:");
tree.nonRecursiveInOrder(root);
System.out.println();

System.out.println("递归后序遍历二叉树结果:");
tree.postOrder(root);
System.out.println();
System.out.println("非递归后序遍历二叉树结果:");
tree.nonRecursivePostOrder(root);
System.out.println();

System.out.println("层次遍历二叉树结果:");
tree.levelTraverse(root);
System.out.println();

System.out.println("递归求二叉树的高度:"+ tree.treeHeight(root));

System.out.println("递归二叉树的结点数:"+ tree.treeNodes(root));

System.out.println("递归二叉树的叶子节点:"+tree.treeLeaf(root));

}
}


输出

递归前序遍历二叉树结果:
1 2 4 7 5 3 6 8 9 10 12 13 11 14
非递归前序遍历二叉树结果:
1 2 4 7 5 3 6 8 9 10 12 13 11 14
递归中序遍历二叉树结果:
4 7 2 5 1 8 6 12 10 13 9 14 11 3
非递归中序遍历二叉树结果:
4 7 2 5 1 8 6 12 10 13 9 14 11 3
递归后序遍历二叉树结果:
7 4 5 2 8 12 13 10 14 11 9 6 3 1
非递归后序遍历二叉树结果:
7 4 5 2 8 12 13 10 14 11 9 6 3 1
层次遍历二叉树结果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
递归求二叉树的高度:6
递归二叉树的结点数:14
递归二叉树的叶子节点:6
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: