劍指offer: 樹的遍歷 (java)

二叉樹基本概念

二叉樹基本概念:
  1) 節點的度。節點所擁有子樹的個數稱爲該節點的度。
  2) 葉節點。度爲0的節點。
  3) 分支節點。度不爲0的節點。
  4) 節點的層數。規定樹的根節點層數爲1,其餘節點的層數爲其雙親節點的層數+1。
  5) 樹的深度。樹中所有節點的最大層數爲樹的深度。
  6) 樹的度。樹中各節點度的最大值爲該樹的度。 
  7) 滿二叉樹。在一棵二叉樹中,所有分支節點都有左子樹和右子樹,且所有葉節點在同一層上。
  8) 完全二叉樹。一個深度爲k有n個節點的二叉樹,對樹中的節點從上到下從左到右的順序進行編號,若編號i
     的節點與滿二叉樹中編號爲i的節點位置相同,那麼這棵二叉樹被稱爲完全二叉樹。
  1) 一棵非空二叉樹的第i層上最多有2^(i-1)個節點。(i>=1)
  2) 一棵深度爲k的二叉樹中,最多具有2^k-1個節點,最少有k個節點。
  3) 對於一棵非空二叉樹,葉節點數n0(度爲0的節點),總比度爲2的節點n2數多一個。即n0=n2+1;
     (二叉樹總的節點數n,葉節點數爲n0,度爲1的節點數n1,度爲2的節點數n2) n=n0+n1+n2;
     二叉樹性質:n=所有節點讀書之和+1,即n=n1+2*n2+1   由上兩式得:n0 = n2 + 1
  4) 具有n個節點的完全二叉樹的深度爲[log2 n] + 1
  5) 對於具有n個節點的完全二叉樹,若編號從1開始,則對於任一的序號爲i的節點:
     若i>1,那麼序號i的雙親節點爲i/2(整除);若i=1,則此節點爲根節點,無雙親節點。
     序號爲i的節點的   左孩子序號爲2*i(2*i<=n), 右孩子的序號爲2*+1(2*i+1<=n)
     若編號從0開始,則對於任一的序號爲i的節點:那麼,序號i的雙親節點爲(i-1)/2,左孩子的編號爲2*i+1,
     右孩子的編號爲2*i+2.
                
排序二叉樹:
  1) 若左子樹不爲空,那麼左子樹上所有節點的值均小於它根節點的值。
  2) 若右子樹不爲空,那麼右子樹上所有節點的值均大於它根節點的值。

 

   運用:遞歸、非遞歸實現先中後序遍歷

   代碼:

// 遞歸實現--先序遍歷
public  void preOrderrecur(Node head) {
	if(head == null) { return ;}
	System.out.print(head.value+"  ");
	preOrderrecur(head.left);
	preOrderrecur(head.right);
}

// 非遞歸實現--先序遍歷
public  void preOrderUnrecur(Node head) {
	System.out.print("pre--Order"+"  ");
	if(head != null) {
		Stack<Node> stack = new Stack<Node>();   // 申請一個棧
		stack.push(head);                        // 將根節點壓入棧中
		while(!stack.isEmpty()) {                // 條件-棧不爲空
			head = stack.pop();                  // 拋出棧頂節點
			System.out.print(head.value+"  ");   // 打印該節點
			// 注意順序不可變
			if(head.right != null) { stack.push(head.right); } // 若有右節點,先存右節點 
			if(head.left != null) { stack.push(head.left); }	
		}
	}
	System.out.println();
}
// 遞歸實現--中序遍歷
public  void inOrderrecur(Node head) {
	if(head == null) {return ;}
	inOrderrecur(head.left);
	System.out.print(head.value+"  ");
	inOrderrecur(head.right);
}

// 非遞歸實現--中序遍歷
public  void inOrderUnrecur(Node head){
	System.out.print("in -- Order"+"  ");
	if(head != null) {
		Stack<Node> stack = new Stack<Node>();     // 申請棧
		while(!stack.isEmpty() || head != null) {
			if(head != null) {          // head 不爲空時,將head存儲到棧中,繼續往左走。
				stack.push(head);
				head = head.left;
			}else{                      // head 爲空時, 從棧中彈出一個元素,並打印,往右走。
				head = stack.pop();
				System.out.print(head.value+"  ");
				head = head.right;
			}
		}
	}
	System.out.println();
}
// 遞歸實現--後序遍歷
public  void posOrderrecur(Node head) {
	if(head == null) {return ;}
	posOrderrecur(head.left);
	posOrderrecur(head.right);
	System.out.print(head.value+"  ");
}

// 非遞歸實現--後序遍歷
public  void posOrderUnrecur(Node head) {
	System.out.print("pos-order: "+"  ");
	if(head == null) { return; }
	if(head != null) {
		Stack<Node> stack = new Stack<Node>();
		Stack<Node> stack1 = new Stack<Node>();
		stack.push(head);
		while(!stack.isEmpty()) {
			head = stack.pop();
			stack1.push(head);
			if( head.left != null) { 
				stack.push(head.left);
			}
			if(head.right != null) { 
				stack.push(head.right);
			}
		}
		while(!stack1.isEmpty()) {
			System.out.print(stack1.pop().value+"  ");
		}
	}
	System.out.println();
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章