二叉搜索樹_BST

来源:https://www.cnblogs.com/Delta2019/archive/2020/05/30/12995691.html
-Advertisement-
Play Games

二叉搜索樹 定義 二叉查找樹(英語:Binary Search Tree),也稱為二叉搜索樹、有序二叉樹(ordered binary tree)或排序二叉樹(sorted binary tree),是指一棵空樹或者具有下列性質的二叉樹: 若任意節點的左子樹不空,則左子樹上所有節點的值均小於它的根節 ...


目錄

二叉搜索樹

定義

二叉查找樹(英語:Binary Search Tree),也稱為二叉搜索樹有序二叉樹(ordered binary tree)或排序二叉樹(sorted binary tree),是指一棵空樹或者具有下列性質的二叉樹

  1. 若任意節點的左子樹不空,則左子樹上所有節點的值均小於它的根節點的值;
  2. 若任意節點的右子樹不空,則右子樹上所有節點的值均大於或等於它的根節點的值;
  3. 任意節點的左、右子樹也分別為二叉查找樹;

推薦講解視頻:

https://www.bilibili.com/video/BV1Qx411m7Lb
https://www.bilibili.com/video/BV1Qx411m7jE
https://www.bilibili.com/video/BV1os411Y7Rt

正月點燈籠@BILIBILI

形式與基本性質

滿二叉樹:

在一棵二叉樹中,如果所有分支結點都有左孩子和右孩子結點,並且葉子結點都集中在二叉樹的最下層,這樣的樹叫做滿二叉樹

完全二叉樹:

若二叉樹中最多只有最下麵兩層的結點的度數可以小於2,並且最下麵一層的葉子結點都是依次排列在該層最左邊的位置上,則稱為完全二叉樹

區別:

滿二叉樹是完全二叉樹的特例,因為滿二叉樹已經滿了,而完全並不代表滿。所以形態你也應該想象出來了吧,滿指的是出了葉子節點外每個節點都有兩個孩子,而完全的含義則是最後一層沒有滿。

二叉樹的五個重要性質:

  1. 在二叉樹的第i層上最多有2 i-1 個節點 。(i>=1)
  2. 二叉樹中如果深度為k,那麼最多有2k-1個節點。(k>=1)
  3. n0=n2+1 n0表示度數為0的節點 n2表示度數為2的節點
  4. 在完全二叉樹中,具有n個節點的完全二叉樹的深度為[log2n]+1,其中[log2n]+1是向下取整。
  5. 若對含 n 個結點的完全二叉樹從上到下且從左至右進行 1 至 n 的編號,則對完全二叉樹中任意一個編號為 i 的結點:
  1. 若 i=1,則該結點是二叉樹的根,無雙親, 否則,編號為 [i/2] 的結點為其雙親結點;
  2. 若 2i>n,則該結點無左孩子, 否則,編號為 2i 的結點為其左孩子結點;
  3. 2i+1>n,則該結點無右孩子結點, 否則,編號為2i+1 的結點為其右孩子結點。

代碼基本實現

實現中大量用了遞歸的方法,可以說遞歸思想是精髓。

#include <bits/stdc++.h>

using namespace std;

struct Node
{
    int data;
    Node *left = nullptr;
    Node *right = nullptr;
};

//迭代方法實現建樹,插入節點
void insertByIterate(Node *&root, int value) //註意root為Node*類型的引用,因為要對root本身進行修改
{
    Node *node = new Node;
    node->data = value;
    if (root == nullptr)
    {
        root = node;
        return;
    }
    else
    {
        Node *temp = root;
        while (temp)
        {
            // if (value == temp->data)  //避免插入重覆元素
            //     return;
            if (value < temp->data)
            {
                if (temp->left)
                {
                    temp = temp->left;
                }
                else
                {
                    temp->left = node;
                    return;
                }
            }
            else
            {
                if (temp->right)
                {
                    temp = temp->right;
                }
                else
                {
                    temp->right = node;
                    return;
                }
            }
        }
    }
}

//遞歸方法實現實現建樹,插入節點
// ! 可能無法記錄父節點,自身層數
void insertByRecursion(Node *&root, int value)
{
    if (root == nullptr)
    {
        root = new Node;
        root->data = value;
        return;
    }
    // if (data == root->data)  //禁止重覆元素
    //     return;
    if (value < root->data)
        insertByRecursion(root->left, value);
    else
        insertByRecursion(root->right, value);
}

void preorder(Node *root) //中序後序同理
{
    if (root)
    {
        cout << root->data << ' ';
        preorder(root->left);
        preorder(root->right);
    }
}

int main(void)
{
    int arr[7] = {6, 1, 2, -10, 4, 5, 7};
    Node *tree = nullptr;
    for (size_t i = 0; i < 7; i++)
    {
        insertByRecursion(tree, arr[i]);
    }
    preorder(tree);
    cout << endl;
    return 0;
}

相關問題

L2-004 這是二叉搜索樹嗎?

一棵二叉搜索樹可被遞歸地定義為具有下列性質的二叉樹:對於任一結點,

  • 其左子樹中所有結點的鍵值小於該結點的鍵值;
  • 其右子樹中所有結點的鍵值大於等於該結點的鍵值;
  • 其左右子樹都是二叉搜索樹。

所謂二叉搜索樹的“鏡像”,即將所有結點的左右子樹對換位置後所得到的樹。

給定一個整數鍵值序列,現請你編寫程式,判斷這是否是對一棵二叉搜索樹或其鏡像進行前序遍歷的結果。

輸入格式:

輸入的第一行給出正整數 N(≤1000)。隨後一行給出 N 個整數鍵值,其間以空格分隔。

輸出格式:

如果輸入序列是對一棵二叉搜索樹或其鏡像進行前序遍歷的結果,則首先在一行中輸出 YES ,然後在下一行輸出該樹後序遍歷的結果。數字間有 1 個空格,一行的首尾不得有多餘空格。若答案是否,則輸出 NO

輸入樣例 1:

7
8 6 5 7 10 8 11

輸出樣例 1:

YES
5 7 6 8 11 10 8

輸入樣例 2:

7
8 10 11 8 6 7 5

輸出樣例 2:

YES
11 8 10 7 5 6 8

輸入樣例 3:

7
8 6 8 5 10 9 11

輸出樣例 3:

NO

思路

題解

#include <bits/stdc++.h>

using namespace std;

struct Node
{
    int data;
    Node *left = 0;
    Node *right = 0;
} *tree = 0;
int n;
typedef vector<int> arr;
void insert(Node *&root, int value)
{
    if (root == 0)
    {
        root = new Node;
        root->data = value;
        return;
    }
    if (value < root->data)
        insert(root->left, value);
    else
        insert(root->right, value);
}
void preOrder(Node *root, vector<int> &res)
{
    if (root)
    {
        res.push_back(root->data);
        preOrder(root->left, res);
        preOrder(root->right, res);
    }
}
void preOrderMirror(Node *root, vector<int> &res)
{
    if (root)
    {
        res.push_back(root->data);
        preOrderMirror(root->right, res);
        preOrderMirror(root->left, res);
    }
}
void postOrder(Node *tree)
{
    static int count(0);
    if (tree)
    {
        postOrder(tree->left);
        postOrder(tree->right);
        cout << tree->data;
        count++;
        if (count != n)
            cout << " ";
    }
}
void postOrderMirror(Node *tree)
{
    static int count(0);
    if (tree)
    {
        postOrderMirror(tree->right);
        postOrderMirror(tree->left);
        cout << tree->data;
        count++;
        if (count != n)
            cout << " ";
    }
}

int main(void)
{
    cin >> n;
    vector<int> input;
    int temp;
    for (int i = 0; i < n; i++)
    {
        cin >> temp;
        insert(tree, temp);
        input.push_back(temp);
    }
    vector<int> res_pre, res_premirror;
    preOrder(tree, res_pre);
    preOrderMirror(tree, res_premirror);
    if (input == res_pre)
    {
        cout << "YES" << endl;
        postOrder(tree);
    }
    else if (input == res_premirror)
    {
        cout << "YES" << endl;
        postOrderMirror(tree);
    }
    else
    {
        cout << "NO" << endl;
    }
    return 0;
}

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

-Advertisement-
Play Games
更多相關文章
  • 從node問世以後,就不斷被JavaScript的忠實追隨者拿來乾一些原來只有php、Python等後端語言才能幹的事情,例如寫個爬蟲之類的。對於前端er來說,用上一些好用的輪子,你可能十幾行代碼就可以寫一個crawler哦~ 爬蟲的思路十分簡單: 按照一定的規律發送 HTTP 請求獲得頁面 HTM ...
  • 1. 需求 將生產環境的流量拷貝到預上線環境或測試環境,這樣做有很多好處,比如: 可以驗證功能是否正常,以及服務的性能; 用真實有效的流量請求去驗證,又不用造數據,不影響線上正常訪問; 這跟灰度發佈還不太一樣,鏡像流量不會影響真實流量; 可以用來排查線上問題; 重構,假如服務做了重構,這也是一種測試 ...
  • 對於學習前端開發有前途嗎?行情怎麼樣,好就業嗎?這樣的問題相信都看了很多很多,每個人的回答都有些差別。但是唯一的一點肯定的,學習前端的前景是很不錯的。 接下來,小編來跟大家分享一下2020年Web前端的發展趨勢如何?熟悉web的小伙伴們都瞭解,自2018年是前端技術的發展相對穩定的一年,就前端主流技 ...
  • 1、打開方式 打開Chrome瀏覽器,按下F12或者右擊空白處然後點擊檢查 最左邊是顯示效果,中間是html代碼,右邊是html樣式。 2、樣式的修改 點擊中間代碼框,左上角的小箭頭,然後點擊css樣式,可以直接修改屬性的值。也可以點擊鍵盤上的上下箭頭,對屬性的值進行修改 需要註意的是,調試工具只是 ...
  • 咕泡三期 Java高級開發|java進階大型互聯網架構師專題 微雲鏈接:鏈接:https://share.weiyun.com/4Ruecunx 密碼:m4xy7s 百度網盤:鏈接: https://pan.baidu.com/s/1UBSJaWNobkTmZ7uTGVMRQg 密碼: 1bpw 如 ...
  • 餓漢式 // 餓漢式單例 public class Hungry { //構造器私有 private Hungry(){ } // 一上來就把這個類載入了 private final static Hungry HUNGRY = new Hungry(); public static Hungry ...
  • 本文講解,Python Tkinter 庫,的基本原理,白話講解,面向小白。 Tkinter 是什麼: Tkinter 是 Python 自帶的一個,標準庫,用於快速創造,簡單的 GUI 程式。 為什麼要瞭解 Tkinter: 首先,因為這個庫,是 Python 自帶的,所以非常方便,隨叫隨到的那種 ...
  • L2-4 部落 在一個社區里,每個人都有自己的小圈子,還可能同時屬於很多不同的朋友圈。我們認為朋友的朋友都算在一個部落里,於是要請你統計一下,在一個給定社區中,到底有多少個互不相交的部落?並且檢查任意兩個人是否屬於同一個部落。 輸入格式: 輸入在第一行給出一個正整數N(≤1e4),是已知小圈子的個數 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...