会当临绝顶,一览众山小

2015.7.5 计划开启,每日更新进度,以此鞭策自己

书单

  1. 算法导论

  2. Javascript高级程序设计

进度

算法导论

红黑树

旋转的本质:中序遍历键值顺序一致

左旋:即以x的右子为父节点,x的新右子为原右子的左节点,最后令新父节点的左节点为x

右旋:即以x的左子为父节点,x的新左子为原左子的右节点,最后令新父节点的右节点为x

rightRotate pseudocode

RightFloat(T, x)
    y = left[x]
    left[x] = right[y]
    
    if right[y] != NULL
        p[right[y]] = x
    
    p[y] = p[x]
    
    if p[x] == NULL
        root[T] = y
    else
        if x == left[p[x]]
            left[p[x]] = y
        else
            right[p[x]] = y
    
    right[y] = x
    p[x] = y

红黑树插入结点

新插入结点置为红结点,有且仅有两种违反红黑树性质的情况

  1. 根结点为红色(即新插入结点为根节点)
  2. 新插入结点的父节点为红色

因此分三种情况调整

  1. z结点的叔父结点为红结点

可将z的父结点及叔父结点变为黑色,将z的祖父结点变为红色,最后将z上移至祖父结点;下一次调整

  1. z结点为右子,且叔父结点为黑色

将z上移至父结点,以z(原z的父节点)为轴,左旋;变为情况3

  1. z结点为左子,且叔父结点为黑色

将z的父结点变为黑色,祖父结点变为红色,将z上移至祖父结点,并以z为轴右旋;下一次调整

实现

TreeNode Definition

struct TreeNode {
    TreeNode():color(true),left(NULL),right(NULL),p(NULL) {}
    TreeNode(int key):key(key),color(true),left(NULL),right(NULL),p(NULL) {}

    bool color; // true: red | false: black
    int key;
    TreeNode* left;
    TreeNode* right;
    TreeNode* p;
};

LeftRotate Implementation

/**
 * assert root->p == NULL && x->right != NULL
 * 
 * @param Tree root node
 * @param Left Rotate node
 */
void leftRotate(TreeNode** root, TreeNode* x) {
    TreeNode* y = x->right;

    // adjust x's right child, i.e. y's left child
    x->right = y->left;
    if (y->left != NULL)
        y->left->p = x;

    // adjust parent child
    y->p = x->p;
    if (x->p == NULL)
        *root = y;
    else
        if (x->p->left == x)
            x->p->left = y;
        else
            x->p->right = y;

    // adjust y's left child, i.e. x
    y->left = x;
    x->p = y;
}

RightRotate Implementation

/**
 * assert root->p == NULL && x->left != NULL
 * 
 * @param Tree root node
 * @param Right Rotate node
 */
void rightRotate(TreeNode** root, TreeNode* x) {
    TreeNode* y = x->left;

    // adjust y right subtree to x left
    x->left = y->right;
    if (y->right != NULL)
        y->right->p = x;

    // adjust parent
    y->p = x->p;
    if (x->p == NULL)
        *root = y;
    else
        if (x->p->left == x)
            x->p->left = y;
        else
            x->p->right = y;

    // push x to y right child
    y->right = x;
    x->p = y;
}

RBInsert Implementation

/**
 * @param
 */
void rBInsert(TreeNode** root, TreeNode* z) {
    TreeNode* y = NULL;
    TreeNode* x = *root;

    while (x != NULL) {
        y = x;
        if (z->key < x->key)
            x = x->left;
        else
            x = x->right;
    }

    z->p = y;

    if (y == NULL)
        *root = z;
    else
        if (z->key < y->key)
            y->left = z;
        else
            y->right = z;

    rbInsertFixUp(root, z);
}

RB-Insert-FIXUP Implementation

/**
 * @param root [description]
 * @param z    [description]
 */
void rbInsertFixUp(TreeNode** root, TreeNode* z) {
    while (z->p != NULL && z->p->color) { // p[z] = red
        TreeNode* y = z->p->p;
        if (y->left == z->p) {
            if (y->right != NULL && y->right->color) { // p[p[z]].right = red
                z->p->color = false;
                y->right->color = false;
                y->color = true;
                z = y;
            } else {
                if (z->p->right == z) {
                    z = z->p;
                    leftRotate(root, z);
                }
                z->p->color = false;
                y->color = true;
                z = y;
                rightRotate(root, z);
            }
        }
        else { // symmetry
            if (y->left != NULL && y->left->color) { // p[p[z]].left = red
                z->p->color = false;
                y->left->color = false;
                y->color = true;
                z = y;
            } else {
                if (z->p->left == z) {
                    z = z->p;
                    rightRotate(root, z);
                }
                z->p->color = false;
                y->color = true;
                z = y;
                leftRotate(root, z);
            }
        }
    }
    (*root)->color = false;
}

BFS for test Implementation

/**
 * @param Tree root node
 */
void BFS(TreeNode* root) {
    if (root == NULL)
        return;

    std::queue<TreeNode*> queue;
    queue.push(root);

    while (!queue.empty()) {
        TreeNode* cur = queue.front();
        queue.pop();

        printf("%d ", cur->key);

        if (cur->left != NULL)
            queue.push(cur->left);

        if (cur->right != NULL)
            queue.push(cur->right);
    }
}

Exercise 13.3.2

/**
 * Exercise 13.3.2
 */
int main(int argc, char const *argv[]) {
    TreeNode* root = NULL;
    TreeNode node1(41);
    TreeNode node2(38);
    TreeNode node3(31);
    TreeNode node4(12);
    TreeNode node5(19);
    TreeNode node6(8);

    rBInsert(&root, &node1);
    rBInsert(&root, &node2);
    rBInsert(&root, &node3);
    rBInsert(&root, &node4);
    rBInsert(&root, &node5);
    rBInsert(&root, &node6);

    BFS(root);

    return 0;
}
    原文作者:哲人善思
    原文地址: https://www.jianshu.com/p/d5922d666c61
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞