1. 程式人生 > >二叉樹面試總結 演算法 java

二叉樹面試總結 演算法 java

二叉樹面試中相關演算法,java實現:

package com.js;

import java.util.LinkedList;
import java.util.Stack;

public class BinaryTree {
	public class TreeRoot{
		int data;
		TreeRoot leftChild = null;
		TreeRoot rightChild = null;
		public TreeRoot(int data){
			this.data = data;
		}
	}
	
	/**
	 * 遞迴方式實現
	 * @param root
	 */
	private void preOrder(TreeRoot root){
		if(root != null){
			System.out.println(root.data);
			preOrder(root.leftChild);
			preOrder(root.rightChild);
		}
	}
	private void inOrder(TreeRoot root){
		if(root != null){
			inOrder(root.leftChild);
			System.out.println(root.data);
			inOrder(root.rightChild);
		}
	}
	private void postOrder(TreeRoot root){
		if(root != null){
			postOrder(root.leftChild);
			postOrder(root.rightChild);
			System.out.println(root.data);
		}
	}
	
	/**
	 * 非遞迴方式實現
	 */
	private void noRecPreOrder(TreeRoot root){
		Stack<TreeRoot> stack = new Stack(); 
		while(root != null || stack.size() > 0){
			while(root != null){
				System.out.println(root.data);
				stack.push(root);
				root = root.leftChild;
			}
			if(stack.size() > 0){
				root = stack.pop();
				root = root.rightChild;
			}
		}
	}
	
	private void noRecInOrder(TreeRoot root){
		Stack<TreeRoot> stack = new Stack();
		while(root != null || stack.size() >0){
			while(root != null){
				stack.push(root);
				root = root.leftChild;
			}
			if(stack.size() > 0){
				root = stack.pop();
				System.out.println(root.data);
				root = root.rightChild;
			}
		}
	}
	
	private void onRecPostOrder(TreeRoot root){
		Stack<TreeRoot> stack = new Stack();
		TreeRoot node = root;
		while(root != null){
			//先左子樹遍歷
			for(;root.leftChild != null;root = root.leftChild){
				stack.push(root);
			}
			//當前節點無右子樹 或者 右子樹已經輸出時
			while(root != null && (root.rightChild == null || root.rightChild == node) ){
				System.out.println(root.data);
				node = root;
				if(stack.empty()){
					return;
				}
				root = stack.pop();
			}
			stack.push(root);
			root = root.rightChild;
		}
	}
	
	
	
	private void noRecPastOrder(TreeRoot root){
		Stack<TreeRoot> stack = new Stack();
		TreeRoot node = root;
		while(root != null){
			//遍歷左子樹 使他入棧
			for(;root != null;root = root.leftChild){
				stack.push(root);
			}
			//右子樹是否等於空 或 右子樹已經輸出
			while(root != null && (root.rightChild ==null || root.rightChild == node)){
				System.out.println(root.data);
				node = root;
				if(stack.empty()){
					return;
				}
				root = stack.pop();
			}
			stack.push(root);
			root  = root.rightChild;
		}
	}
	
	/**
	 * 求葉子節點個數
	 * @param root
	 * @return
	 */
	private int getNodeNum(TreeRoot root){
		if(root == null){
			return 0;
		}else{
			return (getNodeNum(root.leftChild) + 
					getNodeNum(root.rightChild)) +1;
		}
	}
	
	/**
	 * 求二叉樹深度
	 */
	private int getDepth(TreeRoot root){
		if(root == null){
			return 0;
		}else{
			int leftDepth = getDepth(root.leftChild);
			int rightDepth = getDepth(root.rightChild);
			return (leftDepth > rightDepth ? leftDepth:rightDepth)+1;
		}
	}
	
	
	/*
	 * 按層遍歷二叉樹
	 */
	private void levelTree(TreeRoot root){
		LinkedList<TreeRoot> linkList = new LinkedList<>();
		linkList.push(root);
		while(!linkList.isEmpty()){
			TreeRoot cur = linkList.removeFirst();
			System.out.println(cur.data);
			if(cur.leftChild != null){
				linkList.add(cur.leftChild);
			}
			if(cur.rightChild != null){
				linkList.add(cur.rightChild);
			}
		}
	}
	
	/*
	 * 求二叉樹第K層節點個數
	 */
	private int getKNum(TreeRoot root ,int k){
		if(root == null || k < 1){
			return 0;
		}
		if(k == 1){
			return 1;
		}
		int leftNum = getKNum(root,k-1);
		int rightNum = getKNum(root, k-1);
		return leftNum+rightNum;
	}
	
	/**
	 * 判斷兩個二叉樹是否相同
	 */
	public boolean isSameRec(TreeRoot r1,TreeRoot r2){
		if(r1 == null && r2 == null){
			return true;
		}else if(r1 == null || r2 == null){
			return false;
		}
		if(r1.data == r2.data){
			return true;
		}
		boolean leftSame = isSameRec(r1.leftChild,r2.leftChild);
		boolean rightSame = isSameRec(r1.rightChild, r2.rightChild);
		return leftSame && rightSame;
	}
	
	/**
	 * 檢驗二叉樹是否是平衡二叉樹
	 */
	public boolean isAVLRec(TreeRoot root){
		if(root == null){
			return true;
		}
		if(Math.abs(getDepth(root.leftChild) - getDepth(root.rightChild)) > 1){
			return false;
		}
		return isAVLRec(root.leftChild) && isAVLRec(root.rightChild);
	}
}