Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/133.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/three.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 红黑树插入CLRS_C++_Binary Tree_Red Black Tree - Fatal编程技术网

C++ 红黑树插入CLRS

C++ 红黑树插入CLRS,c++,binary-tree,red-black-tree,C++,Binary Tree,Red Black Tree,CLRS 3版中描述的算法看起来是错误的。我试过了,但插入效果不好 #include <iostream> #include <cstdio> #include <cstdlib> #include <ctime> #include <vector> #include <algorithm> using namespace std; const char BLACK = 'B'; const char RED = 'R'

CLRS 3版中描述的算法看起来是错误的。我试过了,但插入效果不好

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <vector>
#include <algorithm>

using namespace std;

const char BLACK = 'B';
const char RED = 'R';

template <class T>
class Node{

    public:
        Node *left;
        Node *right;
        Node *parent;
        char color;
        T key;

        Node(T x){
            this->left = NULL;
            this->right = NULL;
            this->parent = NULL;
            this->key = x;
            this->color = RED;
        };

        virtual ~Node(){};
};

template <class T>
class RedBlackTree{

    private:

        int ammount;
        int h;
        int lastAmmount;
        Node<T> *root;
        Node<T> *NIL;

        void destroy_node(Node<T> *&node);
        Node<T> *remove_node(Node<T> *&node, T x);  // not imeplemented yet
        Node<T> *search_node(Node<T> *&node, T x);  // not imeplemented yet

        void printInfo(Node<T> *&x);
        void printInOrder_node(Node<T> *&node);

        void printInLevel_node(Node<T> *&node, int level);
        int calculeHeight(Node<T> *&node);

        void rotateLeft(Node<T> *&x);
        void rotateRight(Node<T> *&y);
        void insertFixUp(Node<T> *&x);


    public:

        RedBlackTree();
        virtual ~RedBlackTree();
        void destroy();

        void insert(T x);
        void remove(T x);       // not imeplemented yet
        Node<T> *search(T x);   // not implemented yet

        int height();
        void printInOrder();
        void printInLevel();
};


template <class T>
RedBlackTree<T>::RedBlackTree(){

    this->ammount = 0;
    this->lastAmmount = -1;
    this->h = 0;

    this->NIL = new Node<T>(-1);
    this->NIL->color = BLACK;
    this->NIL->left = this->NIL->right = this->NIL->parent = this->NIL;


    this->root = this->NIL;
    this->root->color = BLACK;
}

template <class T>
RedBlackTree<T>::~RedBlackTree(){
    delete this->root;
}



template <class T>
void RedBlackTree<T>::destroy_node(Node<T> *&node){
    if(node != NULL){
        this->destroy(node->left);
        this->destroy(node->right);
        delete node;
    }
}

template <class T>
void RedBlackTree<T>::destroy(){
    this->destroy_node(this->root);
}





// RB methods
template <class T>
void RedBlackTree<T>::rotateLeft(Node<T> *&x){

    Node<T> *y = x->right;
    x->right = y->left;

    if(y->left != this->NIL)
        y->left->parent = x;

    y->parent = x->parent;

    if(x->parent == this->NIL)
        this->root = y;
    else if(x == x->parent->left)
        x->parent->left = y;
    else
        x->parent->right = y;

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


template <class T>
void RedBlackTree<T>::rotateRight(Node<T> *&y){

    Node<T> *x = y->left;
    y->left = x->right;

    if(x->right != this->NIL)
        x->right->parent = y;

    x->parent = y->parent;

    if(y->parent == this->NIL)
        this->root = x;
    else if(y == y->parent->left)
        y->parent->left = x;
    else
        y->parent->right = x;

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


template <class T>
void RedBlackTree<T>::insertFixUp(Node<T> *&z){


    Node<T> *y;

    while(z != this->root and z->parent->color == RED){
        if(z->parent == z->parent->parent->left){
            y = z->parent->parent->right;
            if(y->color == RED){
                z->parent->color = BLACK;
                y->color = BLACK;
                z->parent->parent->color = RED;
                z = z->parent->parent;
            }
            else{
                if(z == z->parent->right){
                    z = z->parent;
                    this->rotateLeft(z);
                }

                z->parent->color = BLACK;
                z->parent->parent->color = RED;
                this->rotateRight(z->parent->parent);
            }
        }
        else{
            y = z->parent->parent->left;
            if(y->color == RED){
                z->parent->color = BLACK;
                y->color = BLACK;
                z->parent->parent->color = RED;
                z = z->parent->parent;
            }
            else{
                if(z == z->parent->left){
                    z = z->parent;
                    this->rotateRight(z);
                }

                z->parent->color = BLACK;
                z->parent->parent->color = RED;
                this->rotateLeft(z->parent->parent);
            }
        }
    }


    this->root->color = BLACK;

}



template <class T>
void RedBlackTree<T>::insert(T val){

    Node<T> *z = new Node<T>(val);
    Node<T> *x = this->root;
    Node<T> *y = this->NIL;

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


    z->parent = y;

    if(y == this->NIL)
        this->root = z;
    else if(z->key < y->key)
        y->left = z;
    else
        y->right = z;


    z->left = this->NIL;
    z->right = this->NIL;
    z->color = RED;

    this->insertFixUp(z);
}





template <class T>
int RedBlackTree<T>::height(){

    if(this->lastAmmount == this->ammount)
        return this->h;

    this->h = this->calculeHeight(this->root);
    this->lastAmmount = this->ammount;
    return this->h;
}


template <class T>
int RedBlackTree<T>::calculeHeight(Node<T> *&node){
    if(node == this->NIL)
        return 0;

    int l_h = this->calculeHeight(node->left);
    int r_h = this->calculeHeight(node->right);

    if(l_h > r_h)
        return l_h+1;

    return r_h+1;
}



template <class T>
void RedBlackTree<T>::printInfo(Node<T> *&x){
    cout << "key=";
    cout << x->key;

    cout << "  l->key=";
    if( x->left == this->NIL) 
        cout << "N";
    else 
        cout << x->left->key;

    cout << "  r->key=";
    if( x->right == this->NIL) 
        cout << "N";
    else 
        cout << x->right->key;

    cout << "  p->key=";
    if( x->parent == this->NIL) 
        cout << "N";
    else 
        cout << x->parent->key;

    cout << "  color=" << x->color << endl;
}

template <class T>
void RedBlackTree<T>::printInOrder_node(Node<T> *&node){
    if(node != this->NIL){
        this->printInOrder_node(node->left);
        //cout << " " << node->key;
        this->printInfo(node);
        this->printInOrder_node(node->right);
    }
}

template <class T>
void RedBlackTree<T>::printInOrder(){
    this->printInOrder_node(this->root);
}



template <class T>
void RedBlackTree<T>::printInLevel(){
    int h = this->height();
    for(int i=1; i<=h; i++)
        this->printInLevel_node(this->root, i);
}


template <class T>
void RedBlackTree<T>::printInLevel_node(Node<T> *&node, int level){
    if(node == this->NIL)
        return;

    if(level == 1)
        this->printInfo(node); //cout << node->key << " ";
    else if(level > 1){
        this->printInLevel_node(node->left, level-1);
        this->printInLevel_node(node->right, level-1);
    }
}





int main(){


    RedBlackTree<int> *bt = new RedBlackTree<int>();

    int v[9] = {11, 2, 14, 1, 7, 15, 5, 8, 4};
    for(int i=0; i<9; i++){
        int x = v[i];
        cout << x << " ";
        bt->insert(x);
    }

    cout << endl;

    cout << "In Level:" << endl; 
    bt->printInLevel();
    cout << endl;



    delete bt;

    return 0;
}
那么,怎么了?
谢谢

考虑添加第二个节点时会发生什么。您可以从以下内容开始:

11 (black)
然后添加新节点:

  11 (black)
 /
2 (red)
然后尝试修复它:

template <class T>
void RedBlackTree<T>::insertFixUp(Node<T> *&z){
  Node<T> *y;

  while(z != this->root and z->parent->color == RED){
    ...
  }
this->root->color = BLACK;
}
模板
void RedBlackTree::insertFixUp(节点*&z){
节点*y;
而(z!=此->根和z->父->颜色==红色){
...
}
此->根->颜色=黑色;
}
请注意,由于
11
一开始是黑色的,因此控件从不进入循环,因此对
insertFixUp
的调用不起任何作用。因此,您将看到一棵红叶树,这不是一棵有效的红黑树。之后,如果您的代码期望在有效的红黑树上工作,那么它很容易出错


可能还有其他错误,但在尝试添加第三个节点之前,应尝试使两个节点的树正常工作。

CLRS使用非常广泛,因此文本中不太可能出现错误。图13.4显示了新插入的节点在树上向上移动时发生的步骤。你可以试着让你的程序在每一步打印出树,以便比较和隔离代码中的错误。A将非常有用。我不这么认为。在此演示中生成示例:。此外,叶子是黑色的,因为每个叶子都是NIL节点(一个黑色节点)。@meitcher:演示中的例子不能改变你问题中代码的有效性,如果你把
NIL
指向的节点称为叶子,那么你的数据结构根本就不是树。我不明白为什么不是树。零只是一个哨兵(如书中所说)。请参见此图片:。注意,因为11一开始是黑色的,所以控制永远不会进入循环“你在说什么?
z
red
节点包含
2
,而不是
11
。根据CLRS,3ed中的定义,那些
NIL
指针被定义为blac,根据该定义,不可能添加红叶。
template <class T>
void RedBlackTree<T>::insertFixUp(Node<T> *&z){
  Node<T> *y;

  while(z != this->root and z->parent->color == RED){
    ...
  }
this->root->color = BLACK;
}