zoukankan      html  css  js  c++  java
  • 《算法导论》笔记 第12章 12.3 插入和删除

    【笔记】

    插入:从根结点开始,沿树下降。指针x跟踪这条路径,而y始终指向x的父结点。根据key[z]与key[x]的比较结果,决定向左向右转。直到x成为NIL为止。这个NIL所占位置及我们想插入z的地方,y即为z的父结点。

    删除:以指向z的指针为参数,考虑三种情况。若z没有子女,则修改其父结点p[z],是NIL为其子女;如果结点z只有一个子女,则可以通过在其子结点与父结点之间建立一条链来删除z。如果结点z有两个子女,先删除z的后继y(它没有左子女),再用y的内容来替代z的内容。


        void treeInsert(NODE *z) {
            NODE *y = NULL;
            NODE *x = root;
            while (x != NULL) {
                y = x;
                if (z->key < x->key) x = x->l;
                else x = x->r;
            }
            z->p = y;
            if (y == NULL) root = z;
            else {
                if (z->key < y->key) y->l = z;
                else y->r = z;
            }
        }
        NODE* treeDelete(NODE* z) {
            NODE *y, *x;
            if (z->l == NULL || z->r ==NULL) y = z;
            else y = treeSuccessor(z);
            if (y->l != NULL) x = y->l;
            else x = y->r;
            if (x != NULL) x->p = y->p;
            if (y->p == NULL) root = x;
            else {
                if (y == y->p->l) y->p->l = x;
                else y->p->r = x;
            }
            if (y != z) {
                z->key = y->key;
            }
            return y;
        }


    对于高度为h的二叉查找树,动态集合操作INSERT和DELETE的运行时间为O(h)。


    【练习】


    12.3-1 给出过程TREE-INSERT的一个递归版本。


        void insert(NODE *rt, NODE *z,NODE *pa = NULL) {
            if (rt == NULL) {
                z->p = pa;
                z->l = z->r = NULL;
                if (pa == NULL) root = z;
                else {
                    if (z->key < pa->key) pa->l = z;
                    else pa->r = z;
                }
                return;
            }
            if (z->key < rt->key) insert(rt->l,z,rt);
            else insert(rt->r,z,rt);
        }



    12.3-2 假设我们通过反复插入不同的关键字的做法来构造一棵二叉查找树。论证:为在树中查找一个关键字,所检查的结点数等于插入该关键字时所检查的结点数+1。

    插入时的比较与查找时的比较几乎完全相同,唯一区别为查找时要多检查插入时的结点。


    12.3-3 可以这样来对n个数进行排序:先构造一棵包含这些数的二叉查找树(重复应用TREE-INSERT来逐个地插入这些数),然后按中序遍历来输出这些数。这个排序算法的最坏情况和最好情况运行时间怎样?

    最坏情况,二叉树退化成链,则构造O(n^2),遍历O(n),运行时间O(n^2)。

    最好情况,二叉树平衡,构造O(nlogn),遍历O(n),运行时间O(nlogn)。


    12.3-4 假设另有一种数据结构中包含指向二叉查找树中某结点y的指针,并假设用过程TREE-DELETE来删除y的前驱z。这样做会出现哪些问题?如何改写TREE-DELETE来解决这些问题?

    有可能指向y的指针已被删除,而y的值已被复制到z。

    将y指向父结点子结点的指针改为与z相同,并改变z的父结点指向z的指针与子结点指向父亲的指针。


    12.3-5 删除操作是可以交换的吗?说明为什么是的,或给出一个反例。



    12.3-6 当TREE-DELETE中的结点z有两个子结点时,可以将其前驱拼接掉。有些人提出了一种公平的策略,即为前驱和后继结点赋予相同的优先级,从而可以得到更好的经验性能。那么,应该如何修改TREE-DELETE来实现这样一种公平的策略?





  • 相关阅读:
    聊聊ES6中的generator
    generator-yield到底是个啥
    jquery 常用方法中那些我不知道的事
    jquery 获取textarea文本值详解
    数组去重
    五指棋人机大战之ai篇
    五指棋人机大战之ui篇
    css控制背景图像不随滚动条的滚动而滚动
    用canvas画会旋转的伞
    CSS3 实现太极图案
  • 原文地址:https://www.cnblogs.com/cyendra/p/3681492.html
Copyright © 2011-2022 走看看