示例#1
0
        public override void Split(TreeNode twoFourNode, int element)
        {
            TwoFourTreeNode p;
            twoFourNode = (TwoFourTreeNode) twoFourNode;

            if (twoFourNode.parent == null)
            {
                p = new TwoFourTreeNode();
            }
            else
            {
                p = (TwoFourTreeNode) twoFourNode.parent;
            }

            TwoFourTreeNode n1 = new TwoFourTreeNode();
            TwoFourTreeNode n2 = new TwoFourTreeNode();

            int[] elements = { element, twoFourNode.elements[0], twoFourNode.elements[1], twoFourNode.elements[2] };
            int middle;
            this.SortElements(elements, elements.Length);

            n1.elements[0] = elements[0];
            n1.elements[1] = elements[1];
            n2.elements[0] = elements[3];
            middle = elements[2];
            n1.parent = p;
            n2.parent = p;

            if (p.NumberOfElements() == 0)
            {
                p.children[0] = n1;
                p.children[1] = n2;
                this.root = p;
            }

            else if (p.NumberOfElements() == 1)
            {
                if (n2.elements[0] < p.elements[0])
                {
                    p.children[2] = p.children[1];
                    p.children[0] = n1;
                    p.children[1] = n2;
                }
                else
                {
                    p.children[1] = n1;
                    p.children[2] = n2;
                }
            }
            else if (p.NumberOfElements() == 2)
            {
                if (n2.elements[0] < p.elements[0] && n2.elements[0] < p.elements[1])
                {
                    p.children[3] = p.children[2];
                    p.children[2] = p.children[1];
                    p.children[0] = n1;
                    p.children[1] = n2;
                }
                else if (n1.elements[1] > p.elements[0] && n1.elements[1] > p.elements[1])
                {
                    p.children[2] = n1;
                    p.children[3] = n2;
                }
                else
                {
                    p.children[3] = p.children[2];
                    p.children[1] = n1;
                    p.children[2] = n2;
                }
            }
            else if (p.NumberOfElements() == 3)
            {
                if (n2.elements[0] < p.elements[0])
                {
                    p.children[4] = p.children[3];
                    p.children[3] = p.children[2];
                    p.children[2] = p.children[1];
                    p.children[1] = n2;
                    p.children[0] = n1;
                }

                else if (n1.elements[0] > p.elements[0] && n2.elements[0] < p.elements[1])
                {
                    p.children[4] = p.children[3];
                    p.children[3] = p.children[2];
                    p.children[2] = n2;
                    p.children[1] = n1;
                }

                else if (n1.elements[0] > p.elements[1] && n2.elements[0] < p.elements[2])
                {
                    p.children[4] = p.children[3];
                    p.children[3] = n2;
                    p.children[2] = n1;
                }
                else
                {
                    p.children[3] = n1;
                    p.children[4] = n2;
                }
            }

            //if it is not a leaf check
            if (twoFourNode.IsLeaf() == false)
            {
                twoFourNode.children[0].parent = n1;
                twoFourNode.children[1].parent = n1;
                twoFourNode.children[2].parent = n1;

                twoFourNode.children[3].parent = n2;
                twoFourNode.children[4].parent = n2;

                n1.children[0] = twoFourNode.children[0];
                n1.children[1] = twoFourNode.children[1];
                n1.children[2] = twoFourNode.children[2];

                n2.children[0] = twoFourNode.children[3];
                n2.children[1] = twoFourNode.children[4];
            }

            if (p.NumberOfElements() == 3)
            {
                this.Split(p, middle);
            }

            else if (p.NumberOfElements() < this.limit)
            {
                p.elements[p.NumberOfElements()] = middle;

                this.SortElements(p.elements, p.NumberOfElements());
            }
        }
示例#2
0
        void TakeElementFromThreeNextRightSibling(TwoFourTreeNode p, TwoFourTreeNode node)
        {
            node.elements[0] = p.elements[0];
            p.elements[0] = p.children[1].elements[0];
            p.children[1].elements[0] = p.elements[1];
            p.elements[1] = p.children[2].elements[0];
            p.children[2].elements[0] = p.elements[2];
            p.elements[2] = p.children[3].elements[0];

            if (p.children[3].NumberOfElements() == 2)
            {
                p.children[3].elements[0] = p.children[3].elements[1];
                p.children[3].elements[1] = 0;
            }

            else if (p.children[3].NumberOfElements() == 3)
            {
                p.children[3].elements[0] = p.children[3].elements[1];
                p.children[3].elements[1] = p.children[3].elements[2];
                p.children[3].elements[2] = 0;
            }

            if (node.IsLeaf() == false)
            {
                node.children[1] = p.children[1].children[0];
                p.children[1].children[0] = p.children[1].children[1];
                p.children[1].children[1] = p.children[2].children[0];
                p.children[2].children[0] = p.children[2].children[1];
                p.children[2].children[1] = p.children[3].children[0];

                if (p.children[3].NumberOfElements() == 1)
                {
                    p.children[3].children[0] = p.children[3].children[1];
                    p.children[3].children[1] = p.children[3].children[2];
                    p.children[3].children[2] = null;
                }
                else if (p.children[3].NumberOfElements() == 2)
                {
                    p.children[3].children[0] = p.children[3].children[1];
                    p.children[3].children[1] = p.children[3].children[2];
                    p.children[3].children[2] = p.children[3].children[3];
                    p.children[3].children[3] = null;
                }

                node.children[1].parent = node;
                p.children[1].children[1].parent = p.children[1];
                p.children[2].children[1].parent = p.children[2];
            }
        }
示例#3
0
        //completes the deletion when node n is empty by either, removing the root, redistributing values, or merging nodes.
        //Note : if n is internal, it has only one child
        public void Fix(TwoFourTreeNode node)
        {
            TwoFourTreeNode p;

            if (node.parent == null) //No parent means it is root node
            {
                if (node.children[0] == null) { return; }
                //remove root and set the children as a root
                this.root = node.children[0];
                this.root.parent = null;
            }

            else
            {
                p = (TwoFourTreeNode)node.parent;

                //situation represents both the possibility of merge and the sibling with two elements
                //if it returns -1, means there is no siblings with two elements
                //if it is bigger than -1, means that index has the two elements
                int situation = this.HasChildWithTwoElement(p);

                //check for redistrubution is possible or not
                if (situation > -1)
                {
                    //redistrubute
                    this.Redistrubute(node, p, situation);
                }

                //redistrubuting not possible, thus merge
                //for merging we have 5 different situation; 2 for parent with one element, 3 for parent with two element
                else
                {
                    this.Merge(node);
                }

                if (node.parent.NumberOfElements() == 0)
                {
                    this.Fix(p);
                }
            }
        }
示例#4
0
        void Redistrubute(TwoFourTreeNode node, TwoFourTreeNode p, int situation)
        {
            //there is two different situation if the parent has two nodes
            if (p.NumberOfElements() == 1)
            {
                if (situation == 20 || situation == 30)
                {
                    this.TakeElementFromNextLeftSibling(p, node, 0);
                }
                else
                {
                    this.TakeElementFromNextRightSibling(p, node, 0);
                }
            }

             //there is six different situation if the parent has three nodes
            else if (p.NumberOfElements() == 2)
            {
                //Check for which children is empty
                if (p.children[0].NumberOfElements() == 0)
                {
                    //situation can be 1 or 2
                    if (situation == 21 || situation == 31)
                    {
                        this.TakeElementFromNextRightSibling(p, node, 0);
                    }
                    else
                    {
                        this.TakeElementFromTwoNextRightSibling(p, node, 0);
                    }
                }
                else if (p.children[1].NumberOfElements() == 0)
                {
                    //situation can be 0 or 2
                    if (situation == 20 || situation == 30)
                    {
                        this.TakeElementFromNextLeftSibling(p, node, 0);
                    }
                    else
                    {
                        this.TakeElementFromNextRightSibling(p, node, 1);
                    }
                }
                else if (p.children[2].NumberOfElements() == 0)
                {
                    //situation can be 0 or 1
                    if (situation == 20 || situation == 30)
                    {
                        this.TakeElementFromTwoNextLeftSibling(p, node, 2);
                    }
                    else
                    {
                        this.TakeElementFromNextLeftSibling(p, node, 1);
                    }
                }
            }
            else if (p.NumberOfElements() == 3)
            {
                //Check for which children is empty
                if (p.children[0].NumberOfElements() == 0)
                {
                    //situation can be 1 2 or 3
                    switch (situation)
                    {
                        case 21:
                            this.TakeElementFromNextRightSibling(p, node, 0);
                            break;
                        case 31:
                            this.TakeElementFromNextRightSibling(p, node, 0);
                            break;
                        case 22:
                            this.TakeElementFromTwoNextRightSibling(p, node, 0);
                            break;
                        case 32:
                            this.TakeElementFromTwoNextRightSibling(p, node, 0);
                            break;
                        case 23:
                            this.TakeElementFromThreeNextRightSibling(p, node);
                            break;
                        case 33:
                            this.TakeElementFromThreeNextRightSibling(p, node);
                            break;
                    }
                }
                else if (p.children[1].NumberOfElements() == 0)
                {
                    //situation can be 0 2 or 3
                    switch (situation)
                    {
                        case 20:
                            this.TakeElementFromNextLeftSibling(p, node, 0);
                            break;
                        case 30:
                            this.TakeElementFromNextLeftSibling(p, node, 0);
                            break;
                        case 22:
                            this.TakeElementFromNextRightSibling(p, node, 1);
                            break;
                        case 32:
                            this.TakeElementFromNextRightSibling(p, node, 1);
                            break;
                        case 23:
                            this.TakeElementFromTwoNextRightSibling(p, node, 1);
                            break;
                        case 33:
                            this.TakeElementFromTwoNextRightSibling(p, node, 1);
                            break;
                    }
                }
                else if (p.children[2].NumberOfElements() == 0)
                {
                    //situation can be 0 1 or 3
                    switch (situation)
                    {
                        case 20:
                            this.TakeElementFromTwoNextLeftSibling(p, node, 2);
                            break;
                        case 30:
                            this.TakeElementFromTwoNextLeftSibling(p, node, 2);
                            break;
                        case 21:
                            this.TakeElementFromNextLeftSibling(p, node, 1);
                            break;
                        case 31:
                            this.TakeElementFromNextLeftSibling(p, node, 1);
                            break;
                        case 23:
                            this.TakeElementFromNextRightSibling(p, node, 2);
                            break;
                        case 33:
                            this.TakeElementFromNextRightSibling(p, node, 2);
                            break;
                    }
                }
                else
                {
                    //situation can be 0 1 or 2
                    switch (situation)
                    {
                        case 20:
                            this.TakeElementFromThreeNextLeftSibling(p, node);
                            break;
                        case 30:
                            this.TakeElementFromThreeNextLeftSibling(p, node);
                            break;
                        case 21:
                            this.TakeElementFromTwoNextLeftSibling(p, node, 3);
                            break;
                        case 31:
                            this.TakeElementFromTwoNextLeftSibling(p, node, 3);
                            break;
                        case 22:
                            this.TakeElementFromNextLeftSibling(p, node, 2);
                            break;
                        case 32:
                            this.TakeElementFromNextLeftSibling(p, node, 2);
                            break;
                    }
                }
            }
        }