二叉搜索樹(Binary Search Tree,BST)

来源:https://www.cnblogs.com/dupengpeng/archive/2023/09/12/17694918.html
-Advertisement-
Play Games

二叉搜索樹(Binary Search Tree,BST) 二叉搜索樹(Binary Search Tree),也稱二叉查找樹或二叉排序樹,是一種特殊的二叉樹,它滿足以下性質 對於二叉搜索樹的每個節點 左子樹中的所有節點的值都小於該節點的值 右子樹中的所有節點的值都大於(或等於)該節點的值 對於二叉 ...


二叉搜索樹(Binary Search Tree,BST)

二叉搜索樹(Binary Search Tree),也稱二叉查找樹或二叉排序樹,是一種特殊的二叉樹,它滿足以下性質

  1. 對於二叉搜索樹的每個節點
    • 左子樹中的所有節點的值都小於該節點的值
    • 右子樹中的所有節點的值都大於(或等於)該節點的值
  2. 對於二叉搜索樹的任意節點,其左子樹和右子樹也是二叉搜索樹。

由於這種特性,二叉搜索樹可以支持高效地進行查找、插入和刪除操作。對於查找操作,可以通過比較目標值與當前節點的值來決定向左子樹還是右子樹進行搜索。對於插入操作,可以按照比較結果找到合適的位置並插入新節點。對於刪除操作,則需要按照一定規則來處理不同情況下的節點刪除

插入節點

在二叉搜索樹中插入一個新節點的步驟如下:

  1. 如果樹為空,將新節點作為根節點。
  2. 如果樹不為空,從根節點開始遍歷樹。
  3. 比較要插入的值與當前節點的值。
    • 如果要插入的值小於當前節點的值,向左子樹方向繼續遍歷。
    • 如果要插入的值大於當前節點的值,向右子樹方向繼續遍歷。
    • 如果要插入的值等於當前節點的值,根據具體需求決定是替換當前節點的值還是忽略該值。
  4. 當遇到空節點時,表示找到了合適的位置插入新節點。
  5. 創建一個新節點,並將其插入到空節點的位置。
  6. 完成插入操作。

示例代碼:

class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;

    public TreeNode(int val) {
        this.val = val;
        this.left = null;
        this.right = null;
    }
}


class BinarySearchTree {
    private TreeNode root;

    public BinarySearchTree() {
        root = null;
    }

    // 插入節點
    public void insert(int val) {
        root = insertNode(root, val);
    }

    private TreeNode insertNode(TreeNode root, int val) {
        // 如果當前節點為空,說明找到了應該插入的位置,創建新節點並返回
        if (root == null) {
            return new TreeNode(val);
        }

        // 如果插入的值小於當前節點的值,向左子樹插入
        if (val < root.val) {
            root.left = insertNode(root.left, val);
        } else if (val > root.val) {
            // 如果插入的值大於當前節點的值,向右子樹插入
            root.right = insertNode(root.right, val);
        }

        return root;
    }
}

搜索節點(查找)

在二叉搜索樹中搜索一個特定值的步驟如下:

  1. 從根節點開始,將要搜索的值與當前節點的值進行比較。
  2. 如果要搜索的值等於當前節點的值,返回true,表示找到了目標值。
  3. 如果要搜索的值小於當前節點的值,則向左子樹方向繼續搜索。
  4. 如果要搜索的值大於當前節點的值,則向右子樹方向繼續搜索。
  5. 如果遇到空節點,則表示未找到目標值,返回false。
  6. 重覆步驟2至步驟5,直到找到目標值或搜索完整個樹。
    下麵是使用上述步驟實現搜索方法的示例代碼:
class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;

    public TreeNode(int val) {
        this.val = val;
        this.left = null;
        this.right = null;
    }
}

class BinarySearchTree {
    // 搜索節點
    public boolean search(int val) {
        return searchNode(root, val);
    }

    private boolean searchNode(TreeNode root, int val) {
        // 當前節點為空,未找到目標值
        if (root == null) {
            return false;
        }

        // 目標值與當前節點的值相等,找到目標值
        if (val == root.val) {
            return true;
        } else if (val < root.val) {
            // 目標值小於當前節點的值,在左子樹中繼續搜索
            return searchNode(root.left, val);
        } else {
            // 目標值大於當前節點的值,在右子樹中繼續搜索
            return searchNode(root.right, val);
        }
    }
}

刪除節點

在二叉搜索樹中刪除一個節點的步驟如下:

  1. 從根節點開始,找到要刪除的節點。
  2. 如果要刪除的值等於當前節點的值,根據下麵不同的情況進行處理:
    a. 若該節點為葉節點(沒有子節點),直接刪除該節點。
    b. 若該節點只有一個子節點,將其子節點替代該節點的位置。
    c. 若該節點有兩個子節點,找到右子樹中最小的節點(或左子樹中最大的節點),將該節點的值替代要刪除的節點的值,然後遞歸刪除該最小節點(或最大節點)。
  3. 如果要刪除的值小於當前節點的值,則向左子樹方向繼續搜索。
  4. 如果要刪除的值大於當前節點的值,則向右子樹方向繼續搜索。
  5. 當遇到空節點時,表示未找到要刪除的節點。
  6. 完成刪除操作。
    下麵是使用上述步驟實現刪除方法的示例代碼:
class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;

    public TreeNode(int val) {
        this.val = val;
        this.left = null;
        this.right = null;
    }
}

class BinarySearchTree {
    private TreeNode deleteNode(TreeNode root, int val) {
        // 當前節點為空,未找到要刪除的節點
        if (root == null) {
            return null;
        }

        // 如果要刪除的值小於當前節點的值,在左子樹中繼續搜索
        if (val < root.val) {
            root.left = deleteNode(root.left, val);
        } else if (val > root.val) {
            // 如果要刪除的值大於當前節點的值,在右子樹中繼續搜索
            root.right = deleteNode(root.right, val);
        } else {
            // 找到要刪除的節點
            // 情況1: 當節點沒有子節點時,直接返回 null
            if (root.left == null && root.right == null) {
                return null;
            }
            // 情況2: 當節點只有一個子節點時,返回子節點作為當前節點的替代
            if (root.left == null) {
                return root.right;
            } else if (root.right == null) {
                return root.left;
            }
            // 情況3: 當節點有兩個子節點時,找到右子樹中最小的節點,
            //       用該節點的值替代當前節點的值,並刪除右子樹中最小的節點
            TreeNode successor = findMin(root.right);
            root.val = successor.val;
            root.right = deleteNode(root.right, successor.val);
        }

        return root;
    }

    private TreeNode findMin(TreeNode node) {
        while (node.left != null) {
            node = node.left;
        }
        return node;
    }
}

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 在今天的移動互聯網時代,手機已經成為了人們不可或缺的重要工具,而手機的聯網狀態也是我們經常需要關註的一個問題。我們需要保證手機網路處於正常的連接狀態,但是有時候,由於種種原因,手機的網路可能會斷開,這時我們需要及時發現,併進行相應的處理措施。而利用Api介面實現手機網路連接斷開的監聽,便是一種較為高 ...
  • 遞歸函數和其他拓展 課前練習 請實現一個裝飾器,把'函數的返回值'+100然後'返回' def ount(fun): def werrod(*ardes,**warrrts): res=fun(*ardes,**warrrts) return res+100 return werrod @ount ...
  • ArrayList/MySQL數據集合寫入Excel 1.文章概述: 寫入 Excel 文件通常需要使用一些庫或工具,而"EasyExcel"通常是指的阿裡巴巴開源的EasyExcel庫。這個庫可以讓我們在Java中簡便地進行Excel文件的讀寫操作。 2.導入配置: <dependency> <g ...
  • 相信很多後端開發。對於前端知識是比較零碎的,所以很多時候寫表單這樣的工作,一般就是複製黏貼,然後改改欄位。對於HTML格式,一直覺得比較雜亂,不夠簡潔。 最近TJ發現了一個有趣的小工具:Create HTML Form。 看看上面它的Slogan,是不是很有意思?居然可以通過Markdown來編寫H ...
  • 如果你的 Python 程式採集到的數據在保存成 CSV 格式的文件時出現了亂碼,那麼可嘗試以下解決方法: 1. 在打開 CSV 文件時指定編碼方式 你可以使用 Python 中的 open() 函數打開 CSV 文件,併在 open() 函數中指定文件編碼方式為 CSV 文件原始編碼方式。如果 C ...
  • 在可執行文件PE文件結構中,通常我們需要用到地址轉換相關知識,PE文件針對地址的規範有三種,其中就包括了`VA`,`RVA`,`FOA`三種,這三種該地址之間的靈活轉換也是非常有用的,本節將介紹這些地址範圍如何通過編程的方式實現轉換。VA(Virtual Address,虛擬地址):它是在進程的虛擬... ...
  • 簡介 說明 本文介紹 Java 內部類持有外部類導致記憶體泄露的原因以及其解決方案。 為什麼內部類持有外部類會導致記憶體泄露 非靜態內部類會持有外部類,如果有地方引用了這個非靜態內部類,會導致外部類也被引用,垃圾回收時無法回收這個外部類(即使外部類已經沒有其他地方在使用了)。 解決方案 不要讓其他的地方 ...
  • 平衡二叉樹(Balanced Binary Tree) 平衡二叉樹是一種特殊的二叉搜索樹,它具有以下特點: 每個節點的左子樹和右子樹的高度差不超過1。 所有的子樹也都是平衡二叉樹。 通過保持平衡性,平衡二叉樹可以在最壞情況下仍然具有較好的性能,保證查找、插入和刪除操作的時間複雜度為O(log n)。 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...