红黑树

/*
 * 红黑树
 *      1 提供基本的操作集:
 *          得到最大结点
 *          得到最小结点
 *          得到后继结点
 *          得到前驱结点
 *          插入结点
 *          删除结点
 *      2 可以扩展的操作
 *          输出一个有序列
 * 本例中没有对重复的元素进行控制
 *
 * NIL 这个思想是从《算法导论》中来的
 * 有了 NIL 所有的结点都是内结点,便于算法的操作
 *
 * Successor 算法需要明白两种情况,没有右孩子,有右孩子
 * InsertNode 算法只插入叶子
 * DeleteNode 算法不删除既有右孩子又有左孩子的结点,这种情况需要转化
 *
 */

#include <cstdio>

#define RED    1
#define BLACK  0
struct RBNode {
    int key;
    int color;
    RBNode *pParent;
    RBNode *pLChild;
    RBNode *pRChild;
};

class CRBTree {
public:
    CRBTree() {
        NIL = new RBNode;
        NIL->color = BLACK;
        NIL->pParent = NIL;
        NIL->pLChild = NIL;
        NIL->pRChild = NIL;

        root = NIL;
    }

    ~CRBTree() {
        delete NIL;
    }

    int GetMaxKey() {
        RBNode *node = GetMaxNode(root);
        if (node == NIL) return 0;
        else return node->key;
    }

    int GetMinKey() {
        RBNode *node = GetMinNode(root);
        if (node == NIL) return 0;
        else return node->key;
    }

    void InsertKey(int key) {
        RBNode *node = new RBNode;
        node->key = key;
        node->color = RED;
        node->pParent = NIL;
        node->pLChild = NIL;
        node->pRChild = NIL;

        InsertNode(node);
    }

    void DeleteKey(int key) {
        RBNode *node;
        while ((node=FindInTree(key)) != NIL) {
            node = DeleteNode(node);
            if (node != NIL) delete node;
        }
    }

    bool KeyInTree(int key) {
        return FindInTree(key) != NIL;
    }

private:
    RBNode *GetMaxNode(RBNode *node) {
        RBNode *p = node;
        while (p->pRChild != NIL) {
            p = p->pRChild;
        }
        return p;
    }

    RBNode *GetMinNode(RBNode *node) {
        RBNode *p = node;
        while (p->pLChild != NIL) {
            p = p->pLChild;
        }
        return p;
    }

    RBNode *FindInTree(int key) {
        RBNode *p = root;
        while (p!=NIL && p->key!=key) {
            if (p->key < key) p = p->pRChild;
            else p = p->pLChild;
        }
        return  p;
    }

    RBNode *Successor(RBNode *node) {
        if (node->pRChild != NIL) return GetMinNode(node->pRChild);

        RBNode *p = node;
        RBNode *pParent = p->pParent;
        while (pParent!=NIL && pParent->pRChild==p) {
            p = pParent;
            pParent = p->pParent;
        }

        return pParent;
    }

    RBNode *Predecessor(RBNode *node) {
        if (node->pLChild != NIL) return GetMaxNode(node->pLChild);

        RBNode *p = node;
        RBNode *pParent = p->pParent;
        while (pParent!=NIL && pParent->pLChild==p) {
            p = pParent;
            pParent = p->pParent;
        }
        return pParent;
    }

    void LeftRotate(RBNode *node) {
        // x y 都不是 NIL
        RBNode *x = node;
        RBNode *y = node->pRChild;

        y->pParent = x->pParent;
        if (x->pParent == NIL) root = y;
        else if (x->pParent->pLChild == x) x->pParent->pLChild = y;
        else x->pParent->pRChild = y;

        x->pRChild = y->pLChild;
        if (x->pRChild != NIL) x->pRChild->pParent = x;

        y->pLChild = x;
        x->pParent = y;
    }

    void RightRotate(RBNode *node) {
        // x y 都不是 NIL
        RBNode *x = node;
        RBNode *y = node->pLChild;
        y->pParent = x->pParent;
        if (x->pParent == NIL) root = y;
        else if (x->pParent->pLChild == x) x->pParent->pLChild = y;
        else x->pParent->pRChild = y;

        x->pLChild = y->pRChild;
        if (x->pLChild != NIL) x->pLChild->pParent = x;

        y->pRChild = x;
        x->pParent = y;
    }

    void InsertNode(RBNode *node) {
        RBNode *p = root;
        RBNode *pParent = NIL;

        while (p != NIL) {
            pParent = p;
            if (p->key < node->key) p = p->pRChild;
            else p = p->pLChild;
        }

        node->pParent = pParent;
        if (pParent == NIL) root = node;
        else if (pParent->key < node->key) pParent->pRChild = node;
        else pParent->pLChild = node;

        node->pLChild = NIL;
        node->pRChild = NIL;
        node->color = RED;

        InsertFixup(node);
    }

    void InsertFixup(RBNode *node) {
        RBNode *z = node;
        while (z->pParent->color==RED) {
            if (z->pParent==z->pParent->pParent->pLChild) {
                if (z->pParent->pParent->pRChild->color==RED) {
                    z->pParent->color =  BLACK;
                    z->pParent->pParent->pRChild->color= BLACK;
                    z->pParent->pParent->color = RED;
                    z = z->pParent->pParent;
                }
                else {
                    if (z->pParent->pRChild == z) {
                        z = z->pParent;
                        LeftRotate(z);
                    }

                    z->pParent->color = BLACK;
                    z->pParent->pParent->color = RED;
                    RightRotate(z->pParent->pParent);
                }
            }
            else {
                if (z->pParent->pParent->pLChild->color == RED) {
                    z->pParent->color = BLACK;
                    z->pParent->pParent->pLChild->color = BLACK;
                    z->pParent->pParent->color = RED;
                    z = z->pParent->pParent;
                }
                else {
                    if (z->pParent->pLChild == z) {
                        z = z->pParent;
                        RightRotate(z);
                    }

                    z->pParent->color = BLACK;
                    z->pParent->pParent->color = RED;
                    LeftRotate(z->pParent->pParent);
                }
            }
        }

        root->color = BLACK;
    }

    RBNode *DeleteNode(RBNode *node) {
        RBNode *p = NIL;
        if (node->pLChild==NIL || node->pRChild==NIL) p = node;
        else p = Successor(node);

        RBNode *pChild = NIL;
        if (p->pLChild != NIL)  pChild= p->pLChild;
        else pChild = p->pRChild;

        pChild->pParent = p->pParent;
        if (p->pParent == NIL) root = NIL;
        else if (p->pParent->pLChild == p) p->pParent->pLChild = pChild;
        else p->pParent->pRChild = pChild;

        if (p != node) {
            int tmp = node->key;
            node->key = p->key;
            p->key = tmp;
        }

        if (p->color == BLACK) DeleteFixup(pChild);

        if (pChild == NIL) pChild->pParent = NIL;

        return p;
    }

    void DeleteFixup(RBNode *x) {
        RBNode *w = NIL;
        while (x != root && x->color==BLACK) {
            if (x->pParent->pLChild == x) {
                w = x->pParent->pRChild;
                if (w->color == RED) {
                    w->color = BLACK;
                    x->pParent->color = RED;
                    LeftRotate(x->pParent);
                    w = x->pParent->pRChild;
                }

                if (w->pLChild->color==BLACK && w->pRChild->color==BLACK) {
                    w->color = RED;
                    x = x->pParent;
                }
                else {
                    if (w->pRChild->color == BLACK) {
                        w->pLChild->color = BLACK;
                        w->color = RED;
                        RightRotate(w);
                        w = w->pParent;
                    }

                    w->color = x->pParent->color;
                    x->pParent->color = BLACK;
                    w->pRChild->color = BLACK;
                    LeftRotate(x->pParent);
                    x = root;
                }

            }
            else {
                w = x->pParent->pLChild;
                if (w->color == RED) {
                    w->color = BLACK;
                    x->pParent->color = RED;
                    RightRotate(x->pParent);
                    w = x->pParent->pLChild;
                }

                if (w->pLChild->color==BLACK && w->pRChild->color==BLACK) {
                    w->color = RED;
                    x = x->pParent;
                }
                else {
                    if (w->pLChild == BLACK) {
                        w->pRChild->color = BLACK;
                        w->color = RED;
                        LeftRotate(w);
                        w = w->pParent;
                    }

                    w->color = x->pParent->color;
                    x->pParent->color = BLACK;
                    w->pLChild->color = BLACK;
                    RightRotate(x->pParent);
                    x = root;
                }
            }
        }
        x->color = BLACK;
    }

private:
    RBNode *NIL;
    RBNode *root;
};

int main() {

    int a[10] = {2, 5, 7, 8, 1, 9 ,10, 3, 4, 6};

    CRBTree btree;
    for (int i=0; i<10; ++i)
        btree.InsertKey(a[i]);

    printf("%d %d\n", btree.GetMinKey(), btree.GetMaxKey());

    btree.DeleteKey(1);
    btree.DeleteKey(10);
    printf("%d %d\n", btree.GetMinKey(), btree.GetMaxKey());

    btree.DeleteKey(5);
    if (btree.KeyInTree(5))
        puts("have found 5 in btree");
    else
        puts("can not find 5 in btree");

    if (btree.KeyInTree(4))
        puts("have found 4 in btree");
    else
        puts("can not find 4 in btree");

    return 0;
}
内容概要:本文档为VMware虚拟机的安装提供了详细的指导。首先明确了安装前计算机应满足的条件,包括操作系统、处理器、内存和硬盘空间的要求。接着介绍了从VMware官网下载Workstation Player的步骤,它是适用于个人用户的免费虚拟机软件。文档详细列出了安装Workstation Player的具体操作流程,包括安装向导指引、许可协议接受以及安装路径的选择。然后重点讲解了创建新虚拟机的步骤,涵盖虚拟机类型的选取、操作系统镜像文件的选择、资源配置及网络设置等。此外,还阐述了操作系统在虚拟机中的安装方法,以及安装后VMware Tools的配置以提升性能和兼容性。最后针对可能出现的问题给出了常见解决方案,如虚拟化技术未开启、虚拟机无法启动和性能问题等,确保用户能顺利完成虚拟机的安装与配置。; 适合人群:对虚拟机有需求但缺乏安装经验的个人用户,尤其是想要进行多操作系统环境下的开发、测试工作的技术人员。; 使用场景及目标:①帮助用户在本地计算机上搭建不同操作系统的运行环境;②为开发、测试等工作提供便捷的虚拟化平台;③解决安装过程中可能遇到的各种问题,确保虚拟机稳定运行。; 其他说明:本教程为简化版本,实际操作时可根据自身情况调整相关设置。若遇困难,可参考官方文档或寻求专业帮助。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值