二叉搜索樹_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
  • 前言 在我們開發過程中基本上不可或缺的用到一些敏感機密數據,比如SQL伺服器的連接串或者是OAuth2的Secret等,這些敏感數據在代碼中是不太安全的,我們不應該在源代碼中存儲密碼和其他的敏感數據,一種推薦的方式是通過Asp.Net Core的機密管理器。 機密管理器 在 ASP.NET Core ...
  • 新改進提供的Taurus Rpc 功能,可以簡化微服務間的調用,同時可以不用再手動輸出模塊名稱,或調用路徑,包括負載均衡,這一切,由框架實現並提供了。新的Taurus Rpc 功能,將使得服務間的調用,更加輕鬆、簡約、高效。 ...
  • 順序棧的介面程式 目錄順序棧的介面程式頭文件創建順序棧入棧出棧利用棧將10進位轉16進位數驗證 頭文件 #include <stdio.h> #include <stdbool.h> #include <stdlib.h> 創建順序棧 // 指的是順序棧中的元素的數據類型,用戶可以根據需要進行修改 ...
  • 前言 整理這個官方翻譯的系列,原因是網上大部分的 tomcat 版本比較舊,此版本為 v11 最新的版本。 開源項目 從零手寫實現 tomcat minicat 別稱【嗅虎】心有猛虎,輕嗅薔薇。 系列文章 web server apache tomcat11-01-官方文檔入門介紹 web serv ...
  • C總結與剖析:關鍵字篇 -- <<C語言深度解剖>> 目錄C總結與剖析:關鍵字篇 -- <<C語言深度解剖>>程式的本質:二進位文件變數1.變數:記憶體上的某個位置開闢的空間2.變數的初始化3.為什麼要有變數4.局部變數與全局變數5.變數的大小由類型決定6.任何一個變數,記憶體賦值都是從低地址開始往高地 ...
  • 如果讓你來做一個有狀態流式應用的故障恢復,你會如何來做呢? 單機和多機會遇到什麼不同的問題? Flink Checkpoint 是做什麼用的?原理是什麼? ...
  • C++ 多級繼承 多級繼承是一種面向對象編程(OOP)特性,允許一個類從多個基類繼承屬性和方法。它使代碼更易於組織和維護,並促進代碼重用。 多級繼承的語法 在 C++ 中,使用 : 符號來指定繼承關係。多級繼承的語法如下: class DerivedClass : public BaseClass1 ...
  • 前言 什麼是SpringCloud? Spring Cloud 是一系列框架的有序集合,它利用 Spring Boot 的開發便利性簡化了分散式系統的開發,比如服務註冊、服務發現、網關、路由、鏈路追蹤等。Spring Cloud 並不是重覆造輪子,而是將市面上開發得比較好的模塊集成進去,進行封裝,從 ...
  • class_template 類模板和函數模板的定義和使用類似,我們已經進行了介紹。有時,有兩個或多個類,其功能是相同的,僅僅是數據類型不同。類模板用於實現類所需數據的類型參數化 template<class NameType, class AgeType> class Person { publi ...
  • 目錄system v IPC簡介共用記憶體需要用到的函數介面shmget函數--獲取對象IDshmat函數--獲得映射空間shmctl函數--釋放資源共用記憶體實現思路註意 system v IPC簡介 消息隊列、共用記憶體和信號量統稱為system v IPC(進程間通信機制),V是羅馬數字5,是UNI ...