手写红黑树

    手写代码遇到了一些问题,先贴代码,以后慢慢讲。

#include <iostream>
#include <queue>
using namespace std;




#define RED 0 // 红色节点
#define BLACK 1 // 黑色节点

typedef int Key;
typedef int Data;

typedef struct _node {
    int color;
    Key key;
    Data data;
    _node * left;
    _node * right;
    _node * parent;
} RBTreeNode;

typedef struct _root {
    RBTreeNode * node;
} RBTreeRoot;


RBTreeRoot * rbtree_init(); // 初始化 root 节点
void rbtree_destroy(RBTreeRoot * ); // 删除创建的红黑树
void _destroy(RBTreeNode * ); // 递归删除节点

void rbtree_left_rotate(RBTreeRoot *, RBTreeNode * );   // 左旋
void rbtree_right_rotate(RBTreeRoot *, RBTreeNode * );  // 右旋
bool rbtree_insert(RBTreeRoot * , RBTreeNode * );    // 插入
void rbtree_insert_fixup(RBTreeRoot *, RBTreeNode * );   // 插入平衡
bool rbtree_delete(RBTreeRoot * , Key );// 依据 key 删除节点
void rbtree_delete_fixup(RBTreeRoot * , RBTreeNode * ,RBTreeNode * ); // 删除平衡


RBTreeNode * rbtree_find(RBTreeRoot * root, Key key); // 查找


void display(RBTreeNode * );   // 中序遍历
void levelDisplay(RBTreeNode * ); // 层次遍历
int cont;


RBTreeRoot * rbtree_init() {
    RBTreeRoot * root = (RBTreeRoot *)malloc(sizeof(RBTreeRoot));
    root->node = NULL;
    return root;
}

void rbtree_destroy(RBTreeRoot * root) {
    _destroy(root->node);
    free(root);
}


void _destroy(RBTreeNode *node) {
    if(node) {
        _destroy(node->left);
        _destroy(node->right);
        free(node);
    }
}

void rbtree_left_rotate(RBTreeRoot * root, RBTreeNode * x) {
    cont++;
    RBTreeNode * y = x->right;
    x->right = y->left;
    if(y->left != NULL) {
        y->left->parent = x;
    }
    y->parent = x->parent;
    if(x->parent == NULL) {  // x 是根节点
        root->node = y;
    } else {
        if(x->parent->left == x) {
            x->parent->left = y;
        } else {
            x->parent->right = y;
        }
    }
    y->left = x;
    x->parent = y;
}


void rbtree_right_rotate(RBTreeRoot * root, RBTreeNode * y) {
    cont++;
    RBTreeNode * x = y->left;
    y->left = x->right;
    if(x->right!=NULL) {
        x->right->parent = y;
    }
    x->parent = y->parent;
    if(y->parent == NULL) {
        root->node = x;
    } else {
        if(y == y->parent->right) {
            y->parent->right = x;
        } else {
            y->parent->left = x;
        }

    }
    x->right = y;
    y->parent = x;
}


bool rbtree_insert(RBTreeRoot * root, RBTreeNode * node) {
    RBTreeNode * x = root->node;
    RBTreeNode * y = NULL;
    // 查找 node 插入的位置
    while(x) {
        y = x;
        if(node->key < x->key) {
            x = x->left;
        } else if(node->key > x->key){
            x = x->right;
        } else {  // 相等 不做插入,返回
            cout << "key : " << node->key << " duplicate!" <<endl;
            return false;
        }
    }

    node->parent = y;
    if(y) {
        if(node->key < y->key) {
            y->left = node;
        } else {
            y->right = node;
        }
    } else {   // root 是空节点
        root->node = node;
    }


    node->color = RED; // 颜色设为红色
    rbtree_insert_fixup(root,node);
    return true;
}

void rbtree_insert_fixup(RBTreeRoot * root, RBTreeNode * node) {
    RBTreeNode * parent;  // 父节点
    RBTreeNode * gparent;  // 祖父节点
    while((parent = node->parent) && (parent->color == RED)) {
        gparent = parent->parent;  // 根据红黑树性质,父节点红色必有祖父节点
        if(parent == gparent->left) {
            // case 1 叔叔节点是红色
            RBTreeNode * uncle = gparent->right;
            if(uncle && (uncle->color == RED)) {
                uncle->color = BLACK;
                parent->color = BLACK;
                gparent->color = RED;
                node = gparent;  // 继续向上调整
                continue;
            }

            // case 2 叔叔节点是黑色
            if(node == parent->right) {   // 插入节点是父节点的右孩子
                rbtree_left_rotate(root,parent);
                RBTreeNode * t = node;
                node = parent;
                parent = t;
            }
            parent->color = BLACK;
            gparent->color = RED;
            rbtree_right_rotate(root,gparent);
        } else {
            // case 1 叔叔节点是红色
            RBTreeNode * uncle = gparent->left;
            if(uncle&& (uncle->color == RED)) {
                uncle->color = BLACK;
                parent->color = BLACK;
                gparent->color = RED;
                node = gparent;  // 继续向上调整
                continue;
            }

            // case 2 叔叔节点是黑色
            if(node == parent->left) {  // 插入节点是父节点的左孩子
                rbtree_right_rotate(root,parent);
                RBTreeNode * t = node;
                node = parent;
                parent = t;
            }
            parent->color = BLACK;
            gparent->color = RED;
            rbtree_left_rotate(root,gparent);
        }
    }
    root->node->color = BLACK;
}

// 依据 key 删除节点
bool rbtree_delete(RBTreeRoot * root, Key key) {
    RBTreeNode * x = root->node;
    RBTreeNode * y = NULL;
    while(x) {
        if(x->key < key) {
            x = x->right;
        } else if(x->key > key) {
            x = x->left;
        } else {
            break;
        }
    }
    if(!x) {
        cout << "key :" << key << " not found!" <<endl;
        return false;
    }
    y = x->parent;
    RBTreeNode * child;
    RBTreeNode * parent;
    if(x->left && x->right) {
        RBTreeNode * r = x->right;
        while(r->left) r = r->left;

        if(y) {
            if(y->left == x) {
                y->left = r;
            } else {
                y->right = r;
            }
        } else {
            root->node = r;
        }

        child = r->right;
        parent = r->parent;
        int color = r->color;

        if(parent == x) {
            parent = r;
        } else {
            if(child) {
                child->parent = parent;
            }
            parent->left = child;
            r->right = x->right;
            x->right->parent = r;
        }
        r->parent = x->parent;
        r->color = x->color;
        r->left = x->left;
        x->left->parent = r;
        if(color == BLACK) rbtree_delete_fixup(root, parent,child);
        free(x);
        return true;
    }

    if(x->left) {   // 注意这里包含了双节点都为空的情况
        child = x->left;
    } else {
        child = x->right;
    }
    parent = x->parent;
    int color = x->color;
    if(child) {
        child->parent = parent;
    }
    if(parent) {
        if(parent->left == x) {
            parent->left = child;
        } else {
            parent->right = child;
        }
    } else {
        root->node = child;
    }
    if(color == BLACK) rbtree_delete_fixup(root, parent, child);
    free(x);
    return true;

}


void rbtree_delete_fixup(RBTreeRoot * root, RBTreeNode * parent, RBTreeNode * node) {  // 调整 node 节点
    RBTreeNode * brother;
    while ((!node || node->color == BLACK) && node != root->node) {   // 三种情况
        if(node == parent->left) {   // node 是 parent 的 左孩子
            brother = parent->right;
            if(brother->color == RED) {  // brother 是红色,parent 肯定是黑色,brother 子节点肯定是黑色
                parent->color = RED; // parent 变为黑色
                brother->color = BLACK;   // brother变成黑色
                rbtree_left_rotate(root,parent);
                brother = parent->right;
            }
            if((!brother->left || (brother->left->color == BLACK)) && ((!brother->right) || (brother->right->color == BLACK))) {   // brother 是黑色,两节点都是黑色
               brother->color = RED;
               node = parent;
               parent = node->parent;
            } else {
                if(!brother->right || (brother->right->color == BLACK)) {  // brother 是黑色,brother 左孩子是红色,右孩子是黑色
                    brother->color = RED;
                    brother->left->color = BLACK;
                    rbtree_right_rotate(root,brother);
                    brother = parent->right;
                }
                brother->color = parent->color;
                parent->color = BLACK;
                brother->right->color = BLACK;
                rbtree_left_rotate(root,parent);
                node = root->node;
                break;
            }
        } else {
            brother = parent->left;
            if(brother->color == RED) {  // brother 是红色,parent 肯定是黑色,brother 子节点肯定是黑色
                parent->color = RED; // parent 变为黑色
                brother->color = BLACK;   // brother变成黑色
                rbtree_right_rotate(root,parent);
                brother = parent->left;
            }
            if((!brother->left || (brother->left->color == BLACK)) && ((!brother->right) || (brother->right->color == BLACK))) {   // brother 是黑色,两节点都是黑色
               brother->color = RED;
               node = parent;
               parent = node->parent;
            } else {
                if(!brother->left || (brother->left->color == BLACK)) {  // brother 是黑色,brother 右孩子是红色,左孩子是黑色
                    brother->color = RED;
                    brother->right->color = BLACK;
                    rbtree_left_rotate(root,brother);
                    brother = parent->left;
                }
                brother->color = parent->color;
                parent->color = BLACK;
                brother->left->color = BLACK;
                rbtree_right_rotate(root,parent);
                node = root->node;
                break;
            }

        }
    }
    if(node) {  // 根节点
        node->color = BLACK;
    }

}

RBTreeNode * rbtree_find(RBTreeRoot * root, Key key) {
    RBTreeNode * x = root->node;
    while(x) {
        if(x->key < key) {
            x = x->right;
        } else if(x->key > key) {
            x = x->left;
        } else {
            break;
        }
    }
    if(x) {
        return x;
    }
    return NULL;

}



void display(RBTreeNode * node) {
    if(node != NULL) {
        //cout << "hello" << endl;
        display(node->left);
        cout << "[" << node->key << "," << node->data << "," << node->color << "]" << "  ";
        display(node->right);
    }
}


void levelDisplay(RBTreeNode * node) {
    if(!node) return ;
    queue<RBTreeNode *> q;
    q.push(node);
    while(!q.empty()) {
        int l = q.size();
        for(int i = 0; i < l; i++) {
            RBTreeNode * node = q.front();
            cout << "[" << node->key << "," << node->data << "," << node->color << "]" << "  ";
            if(node->left) q.push(node->left);
            if(node->right) q.push(node->right);
            q.pop();
        }
        cout << endl;
    }

}



void test_insert(RBTreeRoot * root, int n) {  // 插入 n 个节点
    for(int i = 0; i < n; i++) {
        RBTreeNode * node = (RBTreeNode *)malloc(sizeof(RBTreeNode));
        node->parent = NULL;
        node->left = NULL;
        node->right = NULL;
        node->key = rand() % 1000;
        node->data = rand() % 1000;
        node->color = RED;
        if(!rbtree_insert(root, node)) {   // 插入失败
            free(node);
        }
    }
    levelDisplay(root->node);
}


void test_delete(RBTreeRoot * root, int n) {  // 删除 n 个节点
    for(int i = 0; i < n; i++) {

        Key key = rand() % 1000;
        cout << "delete key :" << key << endl;
        rbtree_delete(root, key);
    }
    levelDisplay(root->node);
}


void test_find(RBTreeRoot * root, int n) {  // 查找 n 个节点
    for(int i = 0; i < n; i++) {
        Key key = rand() % 1000;
        cout << "find key :" << key  << " ";
        RBTreeNode * x = rbtree_find(root, key);
        if(x) {
            cout << " [" << x->key << "," << x->data << "," << x->color << "]" << endl;
        } else {
            cout << "key not find!" << endl;;
        }
    }
}





int main()
{
    RBTreeRoot * root = rbtree_init();
    cont = 0;
    test_insert(root,1136);
    cout << "rotate count :" << cont << endl;
    test_insert(root,1136);
    cout << "rotate count :" << cont << endl;
    test_insert(root,1136);
    cout << "rotate count :" << cont << endl;
    test_delete(root,1130);
    cout << "rotate count :" << cont << endl;
    test_find(root,1600);
    cout << "rotate count :" << cont << endl;
    display(root->node);
    rbtree_destroy(root);

    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值