zoukankan      html  css  js  c++  java
  • 二叉搜索树_BST

    二叉搜索树

    定义

    二叉查找树(英语: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;
    }
    
  • 相关阅读:
    ddd
    对Map按key和value分别排序
    两端通信
    WinDBG调试.NET程序示例
    FAQ:仓储实现为什么在基础设施层?
    Please Send Me a Card
    Web API 入门指南
    Node.js
    聊天工具mychat
    C语言面试问答5
  • 原文地址:https://www.cnblogs.com/Delta2019/p/12995691.html
Copyright © 2011-2022 走看看