二叉樹的構造


二叉樹是很常用的一種數據結構。但是在使用它之前,得先構造一棵二叉樹,下面這篇文章記錄一下如何構造一棵二叉排序樹 和 完全二叉樹。

 

一,給定一組整數,請構造一棵二叉排序樹

比如:2,4,5,1,3

構造二叉排序樹,采用了遞歸方式來構造。

 1     //根據數組 arr 中的元素構造一棵二叉排序樹
 2     public void buildTree(int[] arr){
 3         for (int node : arr) {
 4             insert(node);
 5         }
 6     }
 7     
 8     private void insert(int ele){
 9         root =  insert(root, ele);
10     }
11     
12     private BinaryNode insert(BinaryNode root, int ele){
13         //遞歸的結束條件.base condition
14         if(root == null)
15             return new BinaryNode(ele);
16         
17         if(root.ele > ele)
18             root.left = insert(root.left, ele);
19         else if(root.ele < ele)
20             root.right = insert(root.right, ele);
21         else
22             root.left = insert(root.left, ele);
23         
24         return root;//若某結點的左右孩子不空,在后續的遞歸調用中該結點的左右指針是不會變的.
25     }

 

二,給定一組整數,請按照從上到下,從左到右的順序構造一棵二叉樹(其實就是完全二叉樹)

比如:2,4,5,1,3

構造一棵完全二叉樹,其實這個過程與“二叉樹的按層打印非常相似”。因此,需要一個隊列保存“下一個待構造的結點”。

當某個結點的左右孩子都已經構造完畢時(next==2),從隊列中取出下一個結點,並開始構造它的左右孩子。

 1     public void buildCompleteTree(int[] nodes){
 2         Queue<BinaryNode> queue = new LinkedList<BinaryNode>();
 3         root = new BinaryNode(nodes[0]);
 4         BinaryNode currentNode = null;
 5         
 6 //        queue.offer(root);
 7         int next = 0;//標記當前結點的左右孩子是否已經構造完畢,當next為2時表示當前結點的左右孩子已經構造完畢
 8         currentNode = root;//保存當前正在"構造"的結點
 9         int count = 1;//記錄數組中的已經構造的元素
10         while(count < nodes.length){
11             if(next == 2)//某結點的左右孩子已經構造好了,該結點才能夠 出隊列
12             {
13                 currentNode = queue.poll();
14                 next = 0;
15             }
16             if(currentNode.left == null && count < nodes.length)//完全二叉樹,先構造左孩子
17             {
18                 currentNode.left = new BinaryNode(nodes[count++]);
19                 queue.offer(currentNode.left);
20                 next++;
21             }
22             if(currentNode.right == null && count < nodes.length)//再構造右孩子
23             {
24                 currentNode.right = new BinaryNode(nodes[count++]);
25                 queue.offer(currentNode.right);
26                 next++;
27             }
28         }    
29     }

 

三,完整代碼實現

import java.util.LinkedList;
import java.util.Queue;

public class MyBinarySearchTree {

    private class BinaryNode{
        BinaryNode left;
        BinaryNode right;
        int ele;
        public BinaryNode(int ele) {
            this.ele = ele;
        }
    }
    
    private BinaryNode root;//根節點
    
    //根據數組 arr 中的元素構造一棵二叉排序樹
    public void buildTree(int[] arr){
        for (int node : arr) {
            insert(node);
        }
    }
    
    private void insert(int ele){
        root =  insert(root, ele);
    }
    
    private BinaryNode insert(BinaryNode root, int ele){
        //遞歸的結束條件.base condition
        if(root == null)
            return new BinaryNode(ele);
        
        if(root.ele > ele)
            root.left = insert(root.left, ele);
        else if(root.ele < ele)
            root.right = insert(root.right, ele);
        else
            root.left = insert(root.left, ele);
        
        return root;//若某結點的左右孩子不空,在后續的遞歸調用中該結點的左右指針是不會變的.
    }
    
    public void printTreeLineByLine(BinaryNode root){
        Queue<BinaryNode> queue = new LinkedList<MyBinarySearchTree.BinaryNode>();
        
        int current = 1;//當前層未打印的結點個數
        int next = 0;//下一層待打印的結點個數
        
        queue.offer(root);
        BinaryNode currentNode;
        while(!queue.isEmpty())
        {
            currentNode = queue.poll();
            current--;
            System.out.print(currentNode.ele + " ");//打印當前節點
            
            if(currentNode.left != null)
            {
                queue.offer(currentNode.left);
                next++;
            }
            if(currentNode.right != null)
            {
                queue.offer(currentNode.right);
                next++;
            }
            
            if(current == 0)//表示本行所有的結點已經打印完了
            {
                System.out.println();//打印下一行
                current = next;
                next = 0;
            }
        }
    }
    
    
    public void buildCompleteTree(int[] nodes){
        Queue<BinaryNode> queue = new LinkedList<BinaryNode>();
        root = new BinaryNode(nodes[0]);
        BinaryNode currentNode = null;
        
//        queue.offer(root);
        int next = 0;//標記當前結點的左右孩子是否已經構造完畢
        currentNode = root;//保存當前正在"構造"的結點
        int count = 1;//記錄數組中的已經構造的元素
        while(count < nodes.length){
            if(next == 2)//某結點的左右孩子已經構造好了
            {
                currentNode = queue.poll();
                next = 0;
            }
            if(currentNode.left == null && count < nodes.length)
            {
                currentNode.left = new BinaryNode(nodes[count++]);
                queue.offer(currentNode.left);
                next++;
            }
            if(currentNode.right == null && count < nodes.length)
            {
                currentNode.right = new BinaryNode(nodes[count++]);
                queue.offer(currentNode.right);
                next++;
            }
        }    
    }
    
    
    //test
    public static void main(String[] args) {
        MyBinarySearchTree bst = new MyBinarySearchTree();
        int[] arr = {2,4,5,1,3};
//        bst.buildTree(arr);
//        bst.printTreeLineByLine(bst.root);
        
        System.out.println("----------------");
        
        bst.buildCompleteTree(arr);
        bst.printTreeLineByLine(bst.root);
    }
}
View Code

 

原文地址:博客園hapjin  http://www.cnblogs.com/hapjin/p/5738354.html

 

參考:構造二叉樹,並求解樹的高度

 
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM