java實現二叉樹的建立以及實現二叉查找樹的查、插、刪、遍歷


一、采用存儲結構

   1、順序存儲:采用數組,順序存儲適配於完全二叉樹,對於非完全二叉樹並不合適,主要體現在空間上的浪費,所以我們需要用到另一種存儲方式——鏈式存儲。

            

  2、鏈式存儲:數據data用鍵值對的形式表示

    

 

二、建立二叉樹

//自己建一個Node類,樹有Node對象組成
private class Node{
    private Key key;           //
    private Value val;         //
    private Node left,right;  //左右子樹
    private int N;            //結點計數器
    public Node(Key key,Value val,int N) {
        this.key = key;
        this.val = val;
        this.N = N;
    }
}    
變量N給出了以該節點為根的子樹的結點總數        

三、二叉查找樹的查、插、刪、遍歷

package BSTree;

public class BST_1 <Key extends Comparable<Key>,Value>{
    private Node root;//二叉查找樹的根
    private class Node{
        private Key key;
        private Value value;
        private Node lchild,rchild;
        private int N;    //以該節點為根的子樹中的結點個數
        //構造方法
        public Node(Key key,Value value,int N) {
            this.key = key;
            this.value =value;
            this.N = N;
        }
        @Override
        public String toString() {
            return "Node [key=" + key + ", value=" + value + ", N=" + N + "]";
        }
        
    }
    
    //獲取節點個數N
    public int size() {
        return size(root);
    }
    private int size(Node x) {
        if(x==null) return 0;
        return x.N;
    }
    //通過Key查找Value
    public Value search(Key key)  {
        return search(root,key);
    }
    private Value search(Node x,Key key)  {
        //找不到,返回null
        if(x==null) return null;
        //如果不為空,用待查找的值與當前根節點的值進行比較
        int result = key.compareTo(x.key);//返回一個整數,大於或小於或等於0
        if(result>0) 
            return search(x.rchild, key);//大於,往右子樹遞歸查
        else if(result<0) 
            return search(x.lchild, key);
        else
            return x.value;
    }
    //插入
    public void insert(Key key,Value value){
        root = insert(root,key,value);
    }
    private Node insert(Node x, Key key, Value value) {
        //如果key已經存在,則修改value為新的value值,不存在,則創建一個新的結點
        if(x==null) return new Node(key, value, 1);
        int result = key.compareTo(x.key);
        if(result>0) 
            x.rchild = insert(x.rchild, key, value);
        else if(result<0) 
            x.lchild = insert(x.lchild, key, value);
        else 
            x.value = value;
        x.N = size(x.rchild)+size(x.rchild)+1;        
        return x;
    }
    //查找最小鍵
    public Key min() {
        return min(root).key;
    }
    private Node min(Node x) {
        if(x.lchild==null) return x;
        else return min(x.lchild);
    } 
    //二叉查找樹中最難的就是刪除,先從刪最簡單的最小結點開始
    public void deleteMin() {
        root = deleteMin(root);
    }
    //返回已經刪了最小結點的根節點
    private Node deleteMin(Node x) {
        //在找到最小結點時x時,x=x.right
        if(x.lchild==null) return x.rchild; 
        x.lchild = deleteMin(x.lchild);
        x.N = size(x.rchild)+size(x.rchild)+1;
        return x;        
    }
    /**刪除任意節點
     *   1.如果樹為null或者找不到key,返回null
     *   2.否則,通過比較找到鍵Key的結點:
     *         如果該結點沒有右子樹 ,只有左子樹 x = x.left 
     *         如果該結點沒有左子樹  ,只有有子樹x = x.right
     *         該結點左右子樹都有,先用Node t = x 存x結點,
     *         找到以t.right為根節點的樹的最小鍵, 賦予x: x = min(x.right),及替換x結點
     *         然后把這個最小鍵刪了,把t結點的左子樹賦予x.left
     *   3.返回 返回已經刪了結點的根節點
     *                         
     */
    public void delete(Key key) {
        root = delete(root,key);
    }
    private Node delete(Node x, Key key) {
        if(x==null) return null;
        int result = key.compareTo(x.key);
        if(result>0) x.rchild = delete(x.rchild, key);
        else if(result<0) x.lchild = delete(x.lchild, key);
        else {
            if(x.rchild==null) return x.lchild;
            if(x.lchild==null) return x.rchild;
            Node t = x;
            x = min(t.rchild);
            x.rchild = deleteMin(t.rchild);
            x.lchild = t.lchild;
        }
        x.N = size(x.lchild)+size(x.rchild)+1;
        return x;
    }
    
    //前序遍歷:根--左子樹--右子樹
    public void preOrder() {
        preOrder(root);
    }    
    private void preOrder(Node x) {
        if(x!=null) {
            System.out.print("["+x.key+":"+x.value+"]"+" ");
            preOrder(x.lchild);
            preOrder(x.rchild);
        }
    }
    //中序遍歷:左子樹--根節點--右子樹
    public void inOrder() {
        inOrder(root);
    }
    private void inOrder(Node x) {
        if(x!=null) {
            inOrder(x.lchild);
            System.out.print("["+x.key+":"+x.value+"]"+" ");
            inOrder(x.rchild);
        }
    }
    //后序遍歷:左子樹--右子樹--根節點
    public void postOrder() {
        postOrder(root);
    }
    private void postOrder(Node x) {
        if(x!=null) {
            postOrder(x.lchild);
            postOrder(x.rchild);
            System.out.print("["+x.key+":"+x.value+"]"+" ");
        }
    }
    
}

 


免責聲明!

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



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