Algorithms_二叉树二分搜索树初探
文章目錄
- 二叉樹
- 特征
- 二分搜索樹 Binary Search Tree
- 特征
- 限制(存儲的元素必須具有可比性)
- Code
- 添加數據
- 添加數據V2.0
- 查找 數據
我們簡明扼要的整理下二叉樹,以及二分搜索樹的特征及代碼實現
二叉樹
我們分析下,二叉樹的節點元素 ,除了要存儲數據,還有兩個引用分別指向其他節點
class Node {E e;Node left ; // 左孩子 Node right ; // 右孩子 }特征
-
和鏈表一樣,是動態數據結構
-
每個節點最多只能分出來兩棵樹 (同樣類比多叉樹)
-
二叉樹具有唯一的根節點
按照上圖, 16就是 28根節點的左孩子, 30 就是28的右孩子 。 依次類推 13是16的左孩子, 22是16的右孩子。 29是30的左孩子, 42是30的右孩子。 -
二叉樹每個節點最多有兩個孩子
葉子節點是沒有任何孩子的節點。 上圖是一個完整的二叉樹 ,實際應用中并不都是這種情況。
-
二叉樹每個節點最多有一個父親節點,只有根節點沒有父親節點。
-
二叉樹具有天然的遞歸結構
每個節點的左子樹也是二叉樹
每個節點的右子樹也是二叉樹
-
二叉樹不一定是“滿”的
二分搜索樹 Binary Search Tree
特征
-
二分搜索樹是二叉樹,二叉樹的特征全部適用于二分搜索樹
-
二分搜索樹的每個節點的值
大于其左子樹的所有節點的值
小于其右子樹的所有節點的值
-
每一棵子樹也是二分搜索樹
比如下面的二分搜索樹
限制(存儲的元素必須具有可比性)
為什么要這么設計呢?
其實是為了特定的場景,我們使用二分搜索樹查詢數據的話,這兩個數可以比較的話,那么就可以明確的知道這個數據在左邊還是在右邊了,查詢效率高。
所以什么樣的數據存到二分搜索樹中才能搜索呢? —> 存儲的元素必須具有可比較性
整型自然不必說了,可以比較大小,如果我們存儲的是個對象,那這個對象一定要能比較 。 舉個例子存儲的對象為Car , 要么這個Car 可以按照價格比較,要么可以按照重量比較,總之能比較就可以。
在Java中這個對象要繼承Comparable接口
Code
添加數據
/*** * * @ClassName: BinarySearchTree* * @Description: 二分搜索樹 --> 元素必須可以比較* * @author: Mr.Yang* * @date: 2020年2月8日 下午12:59:02* * @param <E>*/ public class BinarySearchTree<E extends Comparable<E>> {/*** * @ClassName: Node* * @Description: 數據節點類* * @date: 2020年2月8日 下午12:58:44*/private class Node {private E e;// 數據private Node left; // 左孩子private Node right;// 右孩子public Node(E e) {this.e = e;this.left = null;this.right = null;}}private Node root;// 根節點private int size; // 當前數據量/*** * * @Title:BinarySearchTree* * @Description:默認構造函數*/public BinarySearchTree() {this.root = null;this.size = 0;}public int getSize() {return size;}public boolean isEmpty() {return size == 0;}/*** * * @Title: add* * @Description: 向二分搜索樹中添加新的元素e* * @param e* * @return: void*/public void add(E e) {// 根節點的非空判斷if (root == null) {root = new Node(e);size++;} elseadd(root, e);}/*** * * @Title: add* * @Description: 向以node為根的二分搜索樹中插入元素e,遞歸算法* * @param node* @param e* * @return: void*/private void add(Node node, E e) {if (e.equals(node.e))return;else if (e.compareTo(node.e) < 0 && node.left == null) { // 插入到左子樹node.left = new Node(e);size++;return;} else if (e.compareTo(node.e) > 0 && node.right == null) {// 插入到右子樹node.right = new Node(e);size++;return;}// 遞歸調用if (e.compareTo(node.e) < 0)add(node.left, e);else // e.compareTo(node.e) > 0add(node.right, e);} }添加數據V2.0
上面的添加方法,OK ,沒問題。 但代碼量還是有點長
e.compareTo(node.e) >(<) 0 && node.right(left) == null 其實并沒有遞歸到底。
/*** * * @Title: add public 屬性供外部調用* * @Description: 向二分搜索樹中添加新的元素e* * @param e* * @return: void*/public void add(E e) {root = add(root, e);}/*** * * @Title: add 內部調用 私有 遞歸函數* * @Description: 返回插入新節點后的二分搜索樹的根* * @param node* @param e* * @return: void*/private Node add(Node node, E e) {if (node == null) {size++;return new Node(e);}// 相等,不做任何操作if (e.compareTo(node.e) < 0) {node.left = add(node.left, e);} else if (e.compareTo(node.e) > 0) {node.right = add(node.right, e);}return node;}查找 數據
/*** * * @Title: contains 供外部調用* * @Description: 判斷元素e是否存二分搜索樹中* * @param e* * @return: boolean*/public boolean contains(E e) {return contains(root, e);}/*** * * @Title: contains 內部調用* * @Description: 判斷e是否存在于以node為根的二分搜索樹中 遞歸算法* * @param node* @param e* * @return: boolean*/private boolean contains(Node node, E e) {if (node == null) { // node為空 返回falsereturn false;}if (e.compareTo(node.e) == 0) { // 相等 返回truereturn true;} else if (e.compareTo(node.e) < 0) { // 小, 繼續遞歸左子樹return contains(node.left, e);} else { // e.compareTo(node.e) > 0 大, 繼續遞歸右子樹return contains(node.right, e);}} 《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀總結
以上是生活随笔為你收集整理的Algorithms_二叉树二分搜索树初探的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: MySQL-主从复制监控
- 下一篇: Algorithms_二叉树的前序遍历、