• 二叉搜索树


    2.4树的应用——二叉搜索树

    2.4.1二叉搜索树(Binary Search Tree)的定义与性质

    也称为二叉排序树或者二叉搜索树

    性质:

    • 非空左子树的所有键值小于其根结点的键值
    • 非空右子树的所有键值大于其根结点的键值
    • 左、右子树都是二叉搜索树

    2.4.2二叉搜索树的查找

     1 typedef struct TreeNode* BinTree;
     2 struct TreeNode {
     3     int data;
     4     BinTree left;
     5     BinTree right;
     6 };
     7 
     8 //递归查找 查找元素x
     9 BinTree Find(int x, BinTree BST) {
    10     if(BST) {
    11         if (x < BST->data)
    12             return Find(x, BST->left);
    13         else if (x > BST->data)
    14             return Find(x, BST->right);
    15         else
    16             return BST;        
    17     }
    18     return 0;
    19 }
    20 //非递归查找,将尾递归函数转化为迭代函数
    21 BinTree InterFind(int x, BinTree BST) {
    22     if (BST) {
    23         if (x < BST->data)
    24             BST = BST->left;
    25         else if (x > BST->data)
    26             BST = BST->right;
    27         else
    28             return BST;
    29     }
    30     return 0;
    31 }

    归纳:查找的效率取决于树的高度

    查找最大/最小元素:最大元素一定在树的最右边;最小元素一定在树的最左边。

     1 //查找最小元素的递归函数
     2 BinTree FindMin(BinTree BST) {
     3     if (BST) {
     4         if (!BST->left)
     5             return BST;
     6         else
     7             return FindMin(BST->left);
     8     }
     9     return NULL;
    10 }
    11 //查找最大元素的迭代函数
    12 BinTree FinfMax(BinTree BST) {
    13     if (BST) {
    14         while (BST->right)
    15             BST = BST->right;
    16         return BST;
    17     }
    18     return NULL;
    19 }

    2.4.3二叉搜索树的插入

    关键是要找到元素应该插入的位置,但是和Find函数不同的是每次要记住插入结点所在子树的根结点,通过递归的方法把下一层的结构返回,然后连接在一起

     1 BinTree Insert(int x, BinTree BST) {
     2     if (!BST) {//如果树为空
     3         BST = (BinTree)malloc(sizeof(TreeNode));
     4         BST->data = x;
     5         BST->left = NULL;
     6         BST->right = NULL;
     7     }
     8     else {
     9         if (x < BST->data)
    10             BST->left = Insert(x, BST->left);//在左子树中插入,并且将根结点指向被改变的左子树
    11         else
    12             BST->right = Insert(x, BST->right);
    13     }
    14     return BST;//返回的是根结点
    15 }

    2.4.4二叉搜索树的删除

    考虑三种情况:

    • 要删除的是叶结点:直接删除,并修改其父结点指针——置为NULL;
    • 要删除的结点只有一个孩子结点:将其父结点的指针指向要删除结点的孩子结点,即其孙子结点
    • 要删除的结点有左、右两棵树:用另一个结点替代被删除结点,即右子树的最小元素或者左子树的最大元素。其实就是转化成前两种情况,因为最小(最大)元素,一定在最左(最右),一定是叶结点或者只有一个孩子的结点。

     1 BinTree Delete(int x, BinTree BST) {
     2     BinTree tmp;
     3     //如果是空树
     4     if (!BST)cout << "要删除的元素未找到";
     5     //如果没找到待删除结点
     6     else if (x < BST->data)
     7         //将左子树删除之后的新的根结点挂在左边
     8         BST->left = Delete(x, BST->left);
     9     else if (x > BST->data)
    10         BST->right = Delete(x, BST->right);
    11     //如果找到待删除结点
    12     else {
    13         //如果待删除结点有两个孩子
    14         if (BST->left&&BST->right) {
    15             tmp = FindMin(BST->right);
    16             BST->data = tmp->data;//将右子树的最小值的元素覆盖待删除结点
    17             BST->right = Delete(tmp->data, BST->right);//删除替代待删除结点的右子树最小值
    18         }
    19         //如果有一个还是或者没有孩子
    20         else {
    21             tmp = BST;//直接删除待删除结点
    22             //如果没有右孩子,意味着只有左孩子或者没有孩子
    23             if (!BST->right)
    24                 BST = BST->left;
    25             //如果没有左孩子
    26             else if (!BST->left)
    27                 BST = BST->right;
    28             free(tmp);
    29         }
    30     }
    31     return BST;
    32 }
  • 相关阅读:
    Nginx使用GeoIP模块来限制地区访问
    CenTOS7使用ACL控制目录权限,只给某个用户访问特定目录
    CentOS配置服务开机自启
    设置普通用户输入sudo,免密进入root账户
    Centos安装git并配置ssh
    ThreadLocal线程隔离
    Spring cloud 超时配置总结
    Hystrix超时测试
    mysql limit分页查询效率比拼
    linux CPU100%异常排查
  • 原文地址:https://www.cnblogs.com/PennyXia/p/12622109.html
Copyright © 2020-2023  润新知