指针意外修改

时间:2015-05-20 13:17:18

标签: c++ pointers red-black-tree

我按照算法简介对红黑树进行编码。当涉及到右旋转功能时,我的一个指针被意外修改。

 void RBTree::RightRotate(pNode &z)
 {
    pNode l=z->lChild;
    z->lChild = l->rChild;      //link z->l-r to z as a lChild
    if(l->rChild != nil)        
        l->rChild->p = z;       
    l->p = z->p;                //when pass the tree's root as parameter
                                //z,after executing this line, z was 
                                //modified to pointing to nil
                                //(known from debug window), why?
    if(z->p == nil)             
        root = l;
    else if (z == z->p->lChild)
        z->p->lChild = l;
    else
        z->p->rChild = l;
    l->rChild=z;
    z->p=l;
 }

就像算法简介一样,我在班上设置了nil指针。 由于只有当root被传递为参数z才会导致此问题时,我推迟了nilroot的错误。以下是整个代码。 :



    #include 
    #include 
    #include       
    #define RED 1
    #define BLACK 0
    using namespace std;
    typedef struct Node
    {
        int color, val;
        struct Node* lChild, *rChild, *p;
        Node(int val_, struct Node* tmp)   
              {color=RED, val=val_,lChild=rChild=p=tmp;}
        Node(){color=BLACK, val=0,lChild=rChild=p=NULL;}
    }Node,*pNode;

    class RBTree
    {
    public:
        RBTree()
        {
            root=NULL;
        }
        ~RBTree()
        {
            Free_(root);
        }
        void Free_(pNode p)
        {
            if(p!=NULL)
            {
                Free_(p->lChild);
                Free_(p->rChild);
                delete(p);
                p=NULL;
            }
        }
        pNode FindMin() const
        {
            pNode p=root;
            if (p)
                while(p->lChild)
                    p=p->lChild;
            return p;
        }
        pNode FindMax() const
        {
            pNode p=root;
            if (p)
                while(p->rChild)
                    p=p->rChild;
            return p;
        }
        void Print(pNode p, int n) const
        {
            if(!p)
                return;
            Print(p->rChild,n+2);
            for(int i=0;ivalcolor==1)?"R":"B")lChild,n+2);
        }
        pNode Root() {return root;}
        void Insert(int const& val_);
        void InsertFixup(pNode &z);
        void LeftRotate(pNode &p);
        void RightRotate(pNode &p);
        pNode Search(pNode const &p, int x) const;
        void  Delete(pNode &p, int x);

    private:
        pNode root;
        static pNode nil;
    };

    pNode RBTree::nil = new Node();

    /*
    Inserting pipiline:
    Insert node into RBTree, then fixup.
    In the fixup procedure , rotate may be called
     */

    void RBTree::InsertFixup(pNode &z)
    {
        while (z->p->color == RED)
        {
            pNode y;
            if (z->p == z->p->p->lChild)
            {
                y=z->p->p->rChild;
                if(y->color == RED)
                {
                    z->p->color = BLACK;
                    y->color = BLACK;
                    z->p->p->color = RED;
                    z = z->p->p;
                }
                else
                {
                    if(z==z->p->rChild)
                    {
                        z = z->p;
                        LeftRotate(z);
                    }
                    z->p->color = BLACK;
                    z->p->p->color = RED;
                    RightRotate(z->p->p);
                }
            }
            else
            {
                y=z->p->p->lChild;
                if(y->color == RED)
                {
                    z->p->color = BLACK;
                    y->color = BLACK;
                    z->p->p->color = RED;
                    z=z->p->p;
                }
                else
                {
                    if(z==z->p->lChild)
                    {
                        z = z->p;
                        RightRotate(z);
                    }
                    z->p->color = BLACK;
                    z->p->p->color = RED;
                    LeftRotate(z->p->p);
                }
            }
        }
        root->color = BLACK;
    }
    void RBTree::Insert(int const &val_)
    {
        pNode z=new Node(val_, nil);            //set val, lChild, rChild, p to NULL, color to RED
        pNode x = root;
        pNode pre = nil;
        if(NULL == root)
            root = z;
        else
        {
            while (x!=nil)
            {
                pre=x;
                x=(x->valrChild:x->lChild;
            }
            z->p = pre;
            if (z->val val)
                pre->lChild = z;
            else
                pre->rChild = z;
        }
        InsertFixup(z);
    }

    //left-rotate
    //denote z, z's rChild == r
    //parent changed: z, r, r's lChild
    //child chagend:  z->rChild, r->lChild, z->p->lChild/rChild
    void RBTree::LeftRotate(pNode &z)
    {
        pNode r=z->rChild;
        z->rChild = r->lChild;      //link p->r-l to p as a r
        if(r->lChild != nil)
            r->lChild->p = z;
        r->p = z->p;
        if(z->p == nil)
            root = r;
        else if (z == z->p->lChild)
            z->p->lChild = r;
        else
            z->p->rChild = r;

        r->lChild=z;
        z->p=r;
    }
    // right-rotate
    void RBTree::RightRotate(pNode &z)
    {
        pNode l=z->lChild;
        z->lChild = l->rChild;      //link p->l-r to p as a l
        if(l->rChild != nil)
            l->rChild->p = z;
        l->p = z->p;
        if(z->p == nil)             //link parent from top to bottom
            root = l;
        else if (z == z->p->lChild)
            z->p->lChild = l;
        else
            z->p->rChild = l;
        l->rChild=z;
        z->p=l;
    }
    int main()
    {
        int a[9] = {11, 2, 14, 1, 7, 15, 5, 8, 4};
        RBTree tr;
        for(int i=0;i

Am I using nil以错误的方式? 感谢。

1 个答案:

答案 0 :(得分:1)

Nill不是C ++表达式。但是,某些环境可能会包含它,只是将其用作NULL0的别名。如果您使用C ++ 11,我建议nullptr

试着看看是否

l->p< z&& z< l->p + sizeof(z)

如果是这种情况,您将分配给z