二进制红黑树,走回根的最佳方式?

时间:2015-05-22 23:05:00

标签: c# algorithm tree

我正在构建二进制红黑树的过程中。我看到的一个问题是旋转并向后移动到父节点以在旋转后发现黑色红色违规。我不想再次搜索树的最后一个节点,所以我开始为每个节点使用一个后向指针。不确定我的大脑是否被炸了,我不是在考虑这个问题,但如果我不得不再次走到树上寻找:

if (node.left or .right = current) [which gives me a grandparent]

不是我真的把我的插入时间增加到最坏的情况`Log2(n ^ n-1)+ C'

c无论什么时间都等于。

但是,我想,后指针要便宜得多。尽管旋转时重新连接有点棘手,但并不难。所以基本上我不会只是添加恒定时间而是以指数方式增加我的时间吗?

1 个答案:

答案 0 :(得分:0)

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;

using System.Linq;

using System.Text;

using System.Windows.Forms;

namespace RedBlackTree
{
    class RBTree
     {
        public class node {

       public  node right, left, next, back,last;//for traversing the   


          public int id;//for regular implementation
            int day, month, year;//for root @ weeks
            int hour, min;//for shipment times
            byte amPm = 0;//for shipment times
           public char color = 'r';//color of node
           public Object data;//needed data of node

        }
        Queue<node> q = new Queue<node>();
        node head, tail, isRoot;
        node weeks, soNum, custByName;//main roots when customized

        node root = null;//for regular insert
       static Boolean allIsoff = false; 
        //regular insert 
        public void printRoot() {
            MessageBox.Show(root.id.ToString());
        }
        public void insert(int key, Object info) {
            allIsoff = false;
            node child = new node();
            child.id = key;
            child.data = info;
           if(root == null){
               root = child;
               child.color = 'b';
               return;
           }//end root is null

          //setup parent and grandParent nodes
           node parent = null;
           node grandParent = null;
            node GGparent = null;
           addNode(child, root, parent, grandParent,GGparent);


        }//end insert


        //for regular insertion
        private void addNode(node child, node current, node parent, node grandParent,node greatGparent){
           Boolean isTrue = false;//for child and current
           Boolean theRest = false;//for current and parent
           if(current.id == child.id){
               current.data = child.data;
               return;
           }
           if(current.id > child.id ){//going left
               if (current.left == null)
               {

                   current.left = child;//add child to the left
                   isTrue = isRed(current,child);

               }
               else {//continue left 
                   addNode(child, current.left, current, parent,grandParent);


               }


           }//end going left
           else if (current.id < child.id) {//going right 
               if (current.right == null)
               {
                   current.right = child;
                   isTrue = isRed(current, child);
               }
               else {//continue right 
                   addNode(child, current.right, current, parent,grandParent);
               }

           }//end going right

           if (isTrue == false && allIsoff == false)//then check current and parent
           {

               theRest = isRed(current, parent);
               System.Diagnostics.Debug.WriteLine(current.id+" "+parent.id);
           }//end isTrue

           if(isTrue || theRest){//if there is a red clash

                if (isTrue) {
                    if (checkUncle(current, parent))
                    {
                        repaint(parent);
                        isTrue = false;
                    }
                    else
                    {
                        //rotate
                        if (current.id > child.id)
                        {//left of parent
                            if (parent != null)
                            {
                                if (parent.left == current)//P is left of Grandparent
                                {

                                    System.Diagnostics.Debug.WriteLine("T1.A");
                                    current.color = 'b';
                                    parent.color = 'r';
                                    rotateRight(current, parent, grandParent);
                                    allIsoff = true;
                                    return;

                                }
                                else
                                {//P is Right of Grandparent
                                    System.Diagnostics.Debug.WriteLine("T1.B");
                                    child.color = 'b';
                                    parent.color = 'r';
                                    rotateRight(child,current,parent);
                                    rotateLeft(parent,child,grandParent);
                                    allIsoff = true;
                                    return;
                                }


                            }//endif P != null




                        }//end if current > child
                        else {//child is right of current


                            if (parent.left == current)//parent is left of grandparent
                            {
                                System.Diagnostics.Debug.WriteLine("T1.C");
                                rotateLeft(current, child, parent);
                                child.color = 'b';
                                parent.color = 'r';
                                rotateRight(child, parent, grandParent);
                                allIsoff = true;
                                return;

                            }
                            else
                            { //parent is right of grandparent
                                System.Diagnostics.Debug.WriteLine("T1.D");
                                rotateLeft(parent, current, grandParent);
                                current.color = 'b';
                                parent.color = 'r';
                                allIsoff = true;
                                return;
                            }




                        }//end else


                    }//END ELSE


                }//end isTure
                else if (theRest) {

                    if (checkUncle(parent, grandParent))
                    {
                        repaint(grandParent);
                        theRest = false;
                    }
                    else
                    {
                        //rotate
                        if (parent.id > current.id)
                        { //left of parent

                            if (grandParent != null)
                            {
                                if (grandParent.left == parent)//P is left of Grandparent
                                {

                                    System.Diagnostics.Debug.WriteLine("T2.A");
                                    grandParent.color = 'r';
                                    parent.color = 'b';
                                    rotateRight(parent,grandParent,greatGparent);
                                    allIsoff = true;
                                    return;

                                }
                                else
                                {//P is Right of Grandparent
                                    System.Diagnostics.Debug.WriteLine("T2.B");
                                    rotateRight(current, parent, grandParent);
                                    grandParent.color = 'r';
                                    current.color = 'b';
                                    rotateLeft(grandParent, current, greatGparent);
                                    allIsoff = true;
                                    return;
                                }
                            }//what if grandParent is null????????
                            else {
                                if (parent.right.color == 'b')//code should never execute
                                {
                                    System.Diagnostics.Debug.WriteLine("T2.C"); 
                                    current.color = 'b';
                                    rotateRight(current,parent,null);
                                    allIsoff = true;
                                    return;
                                }


                            }//end else for root rotation

                        }
                        else {//right of parent 
                            if (grandParent != null)
                            {
                                if (grandParent.left == parent)//P is left of Grandparent
                                {

                                    System.Diagnostics.Debug.WriteLine("T2.D");
                                    rotateLeft(parent,current,greatGparent);
                                    current.color = 'b';
                                    grandParent.color = 'r';
                                    rotateRight(current,grandParent,greatGparent);
                                    allIsoff = true;
                                    return;

                                }
                                else
                                {//P is Right of Grandparent
                                    System.Diagnostics.Debug.WriteLine("T2.E");
                                    rotateLeft(grandParent,parent,greatGparent);
                                    grandParent.color = 'r';
                                    parent.color = 'b';
                                    allIsoff = true;
                                    return;
                                }
                            }//what if grandParent is null????????
                            else
                            {
                                if (parent.left.color == 'b')//CODE SHOULD NEVER EXECUTE
                                {
                                    System.Diagnostics.Debug.WriteLine("T2.F");
                                    current.color = 'b';
                                    rotateLeft(parent,current,null);
                                    allIsoff = true;
                                    return;
                                }


                            }//end else for root rotation


                        }

                    }//END ELSE

                }

            }//end red clash check


        }//end addNode

        public void repaint(node grandparent) {
            grandparent.right.color = 'b';
            grandparent.left.color = 'b';
            grandparent.color = 'r';
            if (grandparent == root) {
                grandparent.color = 'b';

            }
        }

        public Boolean checkUncle(node parent, node grandparent) {
            if (parent != null) {
                if (grandparent != null) {
                    if (grandparent.left == parent)
                    {
                        if (grandparent.right != null)
                        {
                            if (grandparent.right.color.Equals('r'))
                            {
                                return true;

                            }
                        }

                    }
                    else {
                        if (grandparent.left != null)
                        {
                            if (grandparent.left.color.Equals('r'))
                            {
                                return true;

                            }
                        }

                    }


                }

            }
            return false;
        }//end check uncle

        public Boolean isRed(node a, node b) {
            if (a != null)
            {
                if (a.color.Equals('r'))
                {
                    if (b != null)
                    {
                        if (b.color.Equals('r'))
                        {
                            return true;
                        }
                    }
                }
            }
            return false;

        }


        //inorder traversal for testing
        String inorder = "";

        public void doTraversal() {

            inorderT(root);
        }
        public void inorderT(node current) {

            if (current != null)
            {
                inorder += current.id.ToString() + "(" + current.color.ToString() + "),";

                inorderT(current.left);
                inorderT(current.right);
            }


        }//end inorderT

        public String getInorder() {
            return inorder;
        }

        public void resetInorder() {
            inorder = "";
        }

        public void clearTree() {
            root = null;
        }

        //end methods for inorder traversal for testing
        public void breadthFirst() {




        }



        public void rotateLeft(node p, node q, node grand) {
            if (grand != null)
            {

                System.Diagnostics.Debug.WriteLine("hereRotateLeft !null");

                p.right = q.left;

                q.left = p;
                if (grand.right == p)
                {
                    grand.right = q;

                }
                else { grand.left = q; }
            }
            else {
                System.Diagnostics.Debug.WriteLine("hereRotateLeft else");

                p.right = q.left;

                q.left = p;
                root = q;

            }


        }//end left rotation

        public void rotateRight(node p, node q, node grand)
        {
            if (grand != null)
            {
                System.Diagnostics.Debug.WriteLine("hereRotateRight not null");


                q.left = p.right;

                p.right = q;
                if (grand.right == q)
                {
                    grand.right = p;

                }
                else { grand.left = p; }
            }
            else
            {
                System.Diagnostics.Debug.WriteLine("hereRotateRight else");
                q.left = p.right;

                p.right = q;
                root = p;
            }


        }//end left rotation



        public void addLotForward() {
            for (int l = 0; l < 12; l++ )
            {
                insert(l, "");

            }
        }
      // Queue<node> q = new Queue<node>();

        //following code is for testing, breadth first search
        int[] arr = new int[]{1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384};
        int i =0;
        int b = 0;
        int w = 0;
        int keeper = 0;
        public void BFS()
        {


            q.Enqueue(root);
            while (q.Count > 0)
            {

                node n = q.Dequeue();

                if (i == arr[b])
                {

                    System.Diagnostics.Debug.Write("\r\n"+"("+n.id+""+n.color+")"); 
                    b++;
                    i =0 ;
                }
                else {

                    System.Diagnostics.Debug.Write("(" + n.id + "" + n.color + ")"); 

                }
                i++;


                if (n.id != -1)
                {
                    w = 0;


                    if (n.left != null)
                    {

                        q.Enqueue(n.left);
                    }
                    else
                    {
                        node c = new node();
                        c.id = -1;
                        c.color = 'b';
                        q.Enqueue(c);
                    }

                    if (n.right != null)
                    {

                        q.Enqueue(n.right);
                    }
                    else
                    {
                        node c = new node();
                        c.id = -1;
                        c.color = 'b';
                        q.Enqueue(c);

                    }
                }
                else {
                    w++;
                    node c = new node();
                    c.id = -1;
                    c.color = 'b';
                    q.Enqueue(c);
                    if (w == arr[b])
                    {

                        break;
                    }
                }



            }
            q.Clear();
            w = 0;
            i = 0;
            b = 0;
            System.Diagnostics.Debug.Write("\r\n");
            return;
        }

    }//end main class
}