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

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
时间: 2024-08-29 09:42:59

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

二叉树总结—建树和4种遍历方式(递归&amp;&amp;非递归)

今天总结一下二叉树,要考离散了,求不挂!二叉树最重要的就是 建立.4种遍历方式,简单应用,如何判断两颗二叉树是否相似 二叉树分为 :1.完全二叉树  2.满二叉树 结构性质: 1).满二叉树 高度为h ,节点数则为 2^h - 1,且叶子节点全在最下层,且叶子节点数为2^(n-1)个{n代表二叉树层数,也叫深度} 2).n个节点的 完全二叉树 深度为 int(log2n)(以2为底n的对数)+ 1: 3).非空二叉树 叶子节点个数==双分支节点数+1 4).非空二叉树 某节点编号 n  若有左孩

java组合算法(非递归)

package net.kitbox.util; import java.util.Iterator; import java.util.LinkedList; @SuppressWarnings("rawtypes") public class CombineIterator implements Iterator { //源数据 private int[] source; //结果数组大小 private int resultSize; //结果数组个数 private int s

快速排序递归非递归队列堆栈实现

递归实现 #include<iostream> using namespace std; template <class T> void QuickSort(T A[],int left,int right) { if(left<right) { int i=left; int j=right+1; do { do i++;while(A[i]<A[left]); do j--;while(A[j]>A[left]); if(i<j) Swap(A[i],A

【算法拾遗】二分查找递归非递归实现

转载请注明出处:http://blog.csdn.net/ns_code/article/details/33747953 本篇博文没太多要说的,二分查找很简单,也是常见常考的查找算法,以下是递归非递归的实现. 非递归实现: /* 非递归实现,返回对应的序号 */ int BinarySearch(int *arr,int len,int key) { if(arr==NULL || len<1) return -1; int low = 0; int high = len-1; while(l

Java实现二叉树的创建、递归/非递归遍历

近期复习数据结构中的二叉树的相关问题,在这里整理一下 这里包含: 1.二叉树的先序创建 2.二叉树的递归先序遍历 3.二叉树的非递归先序遍历 4.二叉树的递归中序遍历 5.二叉树的非递归中序遍历 6.二叉树的递归后序遍历 7.二叉树的非递归后序遍历 8.二叉树的层次遍历 这里感谢博客http://blog.csdn.net/skylinesky/article/details/6611442的指导 /**二叉树的结点定义*/ class Node<T>{ private T value; pr

二叉树的前序/中序/后续遍历(递归+非递归)

这几日又把二叉树的递归写了一遍,原来是用C写的,自己写了一个栈,这一次直接用的C++,使用了自带的栈结构.代码如下: 1 /************************************************************************* 2 > Author: Yves 3 > E-mail: [email protected] 4 > File Name: BiTreeNew.cpp 5 > Description: ... 6 > Cre

二叉树,递归非递归遍历算法(全)

包含了所有的非递归和递归的算法: #include<iostream> #include<queue> #include<stack> using namespace std; //二叉树结点的描述 typedef struct BiTNode { char data; struct BiTNode *lchild, *rchild; //左右孩子 }BiTNode,*BiTree; //按先序遍历创建二叉树 //BiTree *CreateBiTree() //返回结

二叉树基础(创建方法,遍历方法(前序/中序/后序/层序、递归/非递归)

二叉树的创建及遍历是很多二叉树问题的基础,递归遍历逻辑清晰,代码简约漂亮,然则效率低下(所有递归方案的通病,非不得已不用递归): 非递归遍历高效,却不是能信手写出来的,特别是后续非递归遍历,相信很多资深码工也有这样的经历: 5年前学习了二叉树的非递归遍历,一个月前复习了并达到能熟练写出的程度,在不参考任何资料的情况下,今天却怎样也写不出来. 如果你也有过这种经历,恭喜你,这说明你是一个正常人…… 另一方面市面上有些国人写的教材,各种语法.逻辑错误层出不起,不知祸害了多少未来的码工,深感痛心. 印

二叉树学习之非递归遍历

二叉树递归遍历可谓是学过数据结构的同仁都能想一下就能写出来,但在应聘过程我们常常遇到的是写出一个二叉树非递归遍历函数,接着上篇文章写二叉树的非递归遍历,先难后易,一步一步的来. 先上代码: #include "binarytree.h" #include <stack> #include <queue> #ifndef RECU #warning("RECU is not defined") /** *前序遍历(根左右) * *1.当前节点为

二叉树的先序、中序以及后序遍历(递归 &amp;&amp; 非递归)

树节点定义: class TreeNode { int val; TreeNode left; TreeNode right; TreeNode(int x) { val = x; } } 递归建立二叉树: //递归建立二叉树 public static void BuildTree(TreeNode node, int data){ if(node == null){ node = new TreeNode(data); } if(data <= node.val){ if(node.left