zoukankan      html  css  js  c++  java
  • 【算法导论】学习笔记——第12章 二叉搜索树

    搜索树数据结构支持多种动态集合操作,包括SEARCH、MINIMUM、MAXIMUM、PREDECESSOR、SUCCESSOR、INSRT和DELETE操作等。基本的搜索树就是一棵二叉搜索树。
    12.1 什么是二叉搜索树
    1. 二叉搜索树的性质:
    设x是二叉搜索树中的一个结点。如果y是x左子树中的一个结点,那么y.key<=x.key。如果y是x右子树中的一个结点,那么y.key>=x.key。
    三种遍历时间复杂度是O(n),这是显然的。

    12.1-3

     1 void Inorder_Tree_Walk_Nonrecursive_1(Node_t *x) {
     2     stack<Node_t *> S;
     3     bool mid = false;
     4 
     5     printf("Using stack to implement Inorder_Tree_Walk:
    ");
     6     S.push(x);
     7     while (!S.empty()) {
     8         if (x->l == NULL || mid) {
     9             printf("%d ", x->key);
    10             S.pop();
    11             if (x->r == NULL) {
    12                 if (S.empty())
    13                     break;
    14                 x = S.top();
    15                 mid = true;
    16             } else {
    17                 x = x->r;
    18                 S.push(x);
    19                 mid = false;
    20             }
    21         } else {
    22             x = x->l;
    23             S.push(x);
    24         }
    25     }
    26     printf("
    ");
    27 }
    28 void Inorder_Tree_Walk_Nonrecursive_2(Node_t *x) {
    29     printf("Using nonstack to implement Inorder_Tree_Walk:
    ");
    30     Node_t *p = x->p, *y = NULL;
    31     bool ret = false, retr = false;
    32 
    33     while (!retr || y!=p) {
    34         if (x->l == NULL || ret) {
    35             if (!retr)
    36                 printf("%d ", x->key);
    37             if (x->r == NULL || retr) {
    38                 retr = (x == y->r);
    39                 x = y;
    40                 y = y->p;
    41                 ret = true;
    42             } else {
    43                 y = x;
    44                 x = x->r;
    45                 ret = false;
    46             }
    47         } else {
    48             y = x;
    49             x = x->l;
    50         }
    51     }
    52     printf("
    ");
    53 }


    12.1-5


    12.2 查询二叉搜索树
    除了基本的SEARCH外,还包括MINIMUM、MAXIMUM、SUCCESSOR、PREDESSOR等查询操作。

    12.2-5


    12.2-6


    12.2-7


    12.2-8


    12.2-9


    12.3 插入和删除
    插入操作比较简,基本二叉树的删除操作需要分类讨论。书中使用了一个子函数TRANSPLANT简化了一些基本操作,使得DELETE过程变得更加清晰。
    插入和删除的时间复杂度都是O(h).

    12.3-2


    12.3-3


    12.3-4
    不可交换,反例如下图:


    12.3-5
    中文的《算法导论(第3版)》这道题完全翻译错了,去看了一下英文的搞懂了题目做的。
    如提示所示,就是利用后继的属性重新实现插入、删除、查找函数。
    求结点p的父节点的思路是先求得p所在子树的最大值,该值所在结点的后继就是p的父节点。 其余
    操作均需要利用后继的性质。以插入为例。

     1 void Tree_Insert(Tree_t *t, Node_t *z) {
     2     Node_t *y = NULL;
     3     Node_t *x = t->root;
     4     while (x != NULL) {
     5         y = x;
     6         if (z->key < x->key)
     7             x = x->l;
     8         else
     9             x = x->r;
    10     }
    11     if (y == NULL) {
    12         t->root = z;    // tree t was empty
    13         z->succ = NULL;
    14     } else if (z->key < y->key) {
    15         Node_t *p = ParentOf(y);
    16         z.succ = y;
    17         p.succ = z;
    18     } else {
    19         z->succ = y->succ
    20         y->succ = z;
    21     }
    22 }

     12.4 随机构建二叉搜索树
    算法导论很多章节都会讲随机算法在数据结构上的随机化。而且都是大段大段的证明,挺犀利。随机算法我个人打算单独花时间学习,因此涉及到的题目都在第二遍读算导的时候再做。
    主要证明一棵有n个不同关键字的随机构建的二叉搜索树的期望高度为O(lgn)。主要随机搜索树的很多基本操作的时间复杂度都是O(lgn)。随机化的效率还是很高的,其实可以写个随机数据发生器,测试一下。

  • 相关阅读:
    水平居中
    flex布局
    get新技能:上传了 flv 或 MP4 文件到服务器,可访问总是出现 “无法找到该页”的 404 错误
    小程序3.8
    小程序3.7
    Vue 中select option默认选中的处理方法
    HTML5 data属性
    静态html返回
    node中可读流、可写流
    node.js fs、http使用
  • 原文地址:https://www.cnblogs.com/bombe1013/p/4292152.html
Copyright © 2011-2022 走看看