Java實現二叉樹的搜索和遍歷


樹是一種常見的數據結構,由一系列節點和節點之間的關係組成。樹的搜索和遍歷是筆試和麪試經常考的。最基本的樹——二叉樹,顧名思義,父節點最多隻有兩個子節點。我們先創建一個樹節點類:

public class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;
    TreeNode(int x) { val = x; }
}

樹的搜索

在這裏插入圖片描述

深度優先搜索(Deep First Search)

深度優先搜索可以採用遞歸實現,代碼如下:

List<Integer> visitList = new ArrayList();
public void dfs(TreeNode root){
    	if(root==null) return;
    	visitList.add(root.val);
    	dfs(root.left);
    	dfs(root.right);
    }

當然,也可以非遞歸的方式,不過此時要藉助棧來實現:

public void dfs(TreeNode root){
       if(root==null){
             return;
       }
       Stack<TreeNode > stack = new Stack<TreeNode >();
       stack.push(node);
       while(!stack.isEmpty()){
             TreeNode rnode = stack.pop();
             visitlist.add(rnode.val);
             if(rnode.right!=null){
                   stack.push(rnode.right);
             }
             if(rnode.left!=null){
                   stack.push(rnode.left);
             }
       }
}

廣度優先搜索(Breadth First Search)

廣度優先搜索藉助隊列的FIFO特性實現,大致思路是:先搜索當前層的節點,然後將左子樹和右子樹添加到隊列中,其Java代碼如下(假設按層輸出):

    public List<List<Integer>> levelOrderBottom(TreeNode root) {
        List<List<Integer>> res = new ArrayList();
        Queue<TreeNode> queue = new LinkedList();
        queue.add(root);     //向隊列中添加根節點
        if(root==null) return res;
        while(!queue.isEmpty()){
            List<Integer> list = new ArrayList();
            Queue<TreeNode> temp = new LinkedList();
            while (!queue.isEmpty()) {
                TreeNode n = queue.remove();
                list.add(n.val);
                if (n.left != null)
                    temp.add(n.left);
                if (n.right != null)
                    temp.add(n.right);
            }
            queue = temp; 
            res.add(list);
        }
        return res;
    }

樹的遍歷

數的遍歷方式可以按照父節點、左子節點、右子節點的訪問順序不同分爲以下三種:前序遍歷,中序遍歷,後序遍歷。

前序遍歷(PreOrder)

先訪問父節點,再訪問左子節點,最後訪問右子節點。那麼對於上面那張圖對應的二叉樹的遍歷順序依次爲:1,2,4,5,3,6,7。可以發現,樹的深度度優先搜索訪問順序和前序遍歷是一樣的。對應的Java代碼如下:

List<Integer> visitList = new ArrayList();
public void preOrder(TreeNode root){
    	if(root==null) return;
    	visitList.add(root.val);
    	preOrder(root.left);
    	preOrder(root.right);
    }

中序遍歷(InOrder)

先訪問左子節點,再訪問父節點,最後訪問右子節點。那麼對於上面那張圖對應的二叉樹的遍歷順序依次爲:4,2,5,1,6,3,7。對應的Java代碼如下:

List<Integer> visitList = new ArrayList();
public void inOrder(TreeNode root){
    	if(root==null) return;
    	inOrder(root.left);
    	visitList.add(root.val);
    	inOrder(root.right);
    }

後序遍歷(PostOrder)

先訪問左子節點,再訪問右子節點,最後訪問父節點。那麼對於上面那張圖對應的二叉樹的遍歷順序依次爲:4,5,2,6,7,3,1。對應的Java代碼如下:

List<Integer> visitList = new ArrayList();
public void postOrder(TreeNode root){
    	if(root==null) return;
    	postOrder(root.left);
    	postOrder(root.right);
    	visitList.add(root.val);
    }

不難發現,其實添加元素的位置的不同就對應了不同的遍歷方式。

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