二叉樹與二叉查找樹的基本方法java實現

轉載自:https://www.cnblogs.com/eudiwffe/p/6207196.html

https://blog.csdn.net/weixin_38629529/article/details/81171245

目錄

1.二叉樹(Binary Tree)

2.完全二叉樹:

3.滿二叉樹:

4.二叉查找樹

5.二叉查找樹基本方法 

1)二叉查找樹表示

2)查找一個元素

3) 插入一個元素

4)樹的遍歷(前序、中序、後序、深度遍歷、廣度遍歷、遞歸與非遞歸)


1.二叉樹(Binary Tree)

一個節點分出兩個節點,稱其爲左右子節點;每個子節點又可以分出兩個子節點,這樣遞歸分叉,其形狀很像一顆倒着的樹。

二叉樹限制了每個節點最多有兩個子節點,沒有子節點的節點稱爲葉子

二叉樹引導出很多名詞概念:

其中節點B只有一個子節點D;

葉子:D, E, F沒有子節點,被稱爲葉子

深度: 指的是根節點到該節點的路徑長度,A的深度爲0,D的深度爲2

高度:只有一個節點的樹,高度爲0,非空樹的高度爲從根結點到最遠的葉結點的路徑長度,習慣上將空樹高度定義爲-1。

出度:節點C分出兩子節點,所以C的出度爲2;

入度:C有且只有一個父節點,所以其入度爲1。 

出度、入度的概念來源於圖(Graph,一種更加高級複雜的數據結構),二叉樹或者說樹形數據結構也是一類特殊的圖,

二叉樹的根節點入度爲0,葉子節點出度爲0。

2.完全二叉樹

除了最高層以外,其餘層節點個數都達到最大值,並且最高層節點都優先集中在最左邊

3.滿二叉樹

除了最高層有葉子節點,其餘層無葉子,並且非葉子節點都有2個子節點。

滿二叉樹一定是一個完全二叉樹,反之則不然

4.二叉查找樹

二叉查找樹(binary search tree,BST)是一種特殊的二叉樹,相對較小的值保存在左節點中,較大的值保存在右節點中。

二叉查找樹(沒有重複元素)的特徵是:對於樹中的每一個結點,它的左子樹中結點的值都小於該結點的值,而它的右子樹中結點的值都大於該結點的值。

5.二叉查找樹基本方法 

轉載自:《Java語言程序設計進階篇》

1)二叉查找樹表示

使用一個鏈式結點的集合來表示二叉樹。每個結點都包含一個數值和兩個稱爲left和right的鏈接,分別指向左孩子和右孩子,如圖所示

節點可以定義爲一個類:E是泛型,表示該節點可以放不同的類型

class TreeNode<E> {
    protected E element;
    protected TreeNode left;
    protected TreeNode right;
    public TreeNode(E element) {
        this.element = element;
    }
}

創建一顆樹:

 代碼如下:

        TreeNode<Integer> root = new TreeNode<>(60);
        root.left = new TreeNode(50);
        root.right = new TreeNode(70);

變量root指向樹的根結點。如果樹爲空,那root的值爲null

2)查找一個元素

要在二叉查找樹中查找一個元素,可從根結點開始向下掃描,直到找到一個匹配元素,或者達到一棵空子樹爲止。

該算法在程序清單1中描述。讓current指向根結點,

重複下面的步驟直到current爲null或者元素匹配current.element:

如果element小於current.element,就將current.left賦給current

如果element大於current.element,就將current.right賦給current

如果element等於current.element,就返回true

如果current爲null,那麼子樹爲空且該元素不在這棵樹中 返回false

    public boolean search(E element){
        TreeNode<E> current = root;
        while(current!=null){
            if (element < current.element){
                current = current.left;
            }else if(element > current.element){
                current = current.right
            }else
            return true;
        
        }
        return false;
    }

3) 插入一個元素

爲了在BST中插入一個元素,需要確定在樹中插入元素的位置。關鍵思路是確定新結點的父結點所在的位置

若當前樹不爲空,尋找新元素結點的父結點位置。 如果新元素小於父元素值,設置爲左子節點,大於則設置爲右子節點。

4)樹的遍歷

樹的遍歷(tree traversal)就是訪問樹中每個結點一次且只有一次的過程。

中序(inorder)、前序(preorder)、後序(postorder)、深度優先(depth-first)和廣度優先(breadth-first)等遍歷方法。

A 中序遍歷(inorder traversal)法

首先遞歸地訪問當前結點的左子樹,然後訪問當前結點,最後遞歸地訪問該結點的右子樹。中序遍歷法以遞增順序顯示BST中的所有結點。

B 後序遍歷(postorder traversal)法,首先遞歸地訪問當前結點的左子樹,然後遞地訪問該結點的右子樹,最後訪問該結點本身。後序遍歷的一個應用就是找出一個文件系統中目錄的個數。

C 前序遍歷(preorder traversal)法,首先訪問當前結點,然後遞歸地訪問該結點的左子樹,最後遞歸地訪問該結點的右子樹

D 深度優先遍歷法與前序遍歷法相同。

E 廣度優先遍歷法逐層訪問樹中的結點。首先訪問根結點,然後從左往右訪問根結點的所有子結點,再從左往右訪問根結點的所有孫子結點,以此類推。

public class TreeNode {
    protected int data;
    protected TreeNode left;
    protected TreeNode right;
    public TreeNode(int data) {
        this.data = data;
    }

    /**遞歸 就是有調用自己————————————*/
    /**前序遞歸遍歷*/
    public  static void preOrder(TreeNode root){
        if (root != null){
            System.out.print(root.data+"\t");
            preOrder(root.left);
            preOrder(root.right);
        }
    }

    /**中序遞歸遍歷*/
    public static void inOrder(TreeNode root){
        if (root != null){
            inOrder(root.left);
            System.out.print(root.data+"\t");
            inOrder(root.right);
        }
    }
    /**後序遞歸遍歷*/
    public static void postOrder(TreeNode root){
        if (root != null){
            postOrder(root.left);
            postOrder(root.right);
            System.out.print(root.data+"\t");
        }
    }
    /**非遞歸-----------非遞歸寫法一定會用到棧-------------------*/
//    如何寫非遞歸代碼呢?
// 一句話:讓代碼跟着思維走。我們的思維是什麼?思維就是中序遍歷的路徑。
//    首先,我們遍歷左子樹,邊遍歷邊打印,並把根節點存入棧中,
//    以後需藉助這些節點進入右子樹開啓新一輪的循環。
//    接下來就是:出棧,根據棧頂節點進入右子樹。
    /**前序非遞歸遍歷*/
    public static void preOrderNoRe(TreeNode root){
        Stack<TreeNode> s = new Stack<>();
        while (root != null || !s.empty()) {
            //邊遍歷 邊打印 將根節點存入棧中
            while (root !=null){
                System.out.print(root.data+"\t");
                s.push(root);
                root = root.left;
            }
            if (!s.empty()){
                root = s.pop();
                root = root.right;
            }
        }

    }

    // 中序遍歷非遞歸
    public static void inOrderNoRe(TreeNode root) {
        Stack<TreeNode> s = new Stack<TreeNode>();
        while (root != null || !s.empty()) {
            while (root != null) {
                s.push(root);
                root = root.left;
            }
            if (!s.empty()) {
                root = s.pop();
                System.out.print(root.data+"\t");
                root = root.right;
            }
        }
    }

    // 後序遍歷非遞歸
    public static void postOrderNoRe(TreeNode root) {
        Stack<TreeNode> s = new Stack<TreeNode>();
        Stack<Integer> s2 = new Stack<Integer>();
        Integer i = new Integer(1);
        while (root != null || !s.empty()) {
            while (root != null) {
                s.push(root);
                s2.push(new Integer(0));
                root = root.left;
            }
            while (!s.empty() && s2.peek().equals(i)) {
                s2.pop();
                System.out.print(s.pop().data+"\t");
            }

            if (!s.empty()) {
                s2.pop();
                s2.push(new Integer(1));
                root = s.peek();
                root = root.right;
            }
        }
    }


}

5)刪除BST中的一個元素

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