二叉搜索树_BST

0
11

目录

  • 二叉搜索树
    • 定义
    • 形式与基本性质
    • 代码基本实现
    • 相关问题
      • L2-004 这是二叉搜索树吗?
        • 输入格式:
        • 输出格式:
        • 思路
        • 题解

二叉搜索树

定义

二叉查找树(英语: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;
}

<

发布回复

请输入评论!
请输入你的名字