Example #1
0
        /// <summary>
        /// Removes element from the tree.
        /// </summary>
        /// <param name="data">
        /// Element to be removed.
        /// </param>
        /// <returns>
        /// The remove.
        /// </returns>
        public override bool Remove(T data)
        {
            _23TreeNode <T> node = this.Delete(this._root, data);

            if (node == null)
            {
                return(false);
            }

            while (node.Parent != null)
            {
                node = (_23TreeNode <T>)node.Parent;
            }

            if (node.Values.Count > 0)
            {
                this._root = node;
            }
            else
            {
                this._root = null;
            }

            return(true);
        }
Example #2
0
 /// <summary>
 /// Initializes a new instance of the <see cref="_23TreeNode{T}"/> class.
 /// Constructor.
 /// </summary>
 /// <param name="parent">
 /// Parent node.
 /// </param>
 /// <param name="data">
 /// Values for the node.
 /// </param>
 public _23TreeNode(_23TreeNode <T> parent, List <T> data)
     : base(data, null)
 {
     this._parent   = parent;
     this.Values    = data;
     this.Neighbors = null;
     this._isLeaf   = true;
 }
Example #3
0
        /// <summary>
        /// Adds input node values and child nodes .
        /// </summary>
        /// <param name="node">
        /// Input node.
        /// </param>
        public _23TreeNode <T> Add(_23TreeNode <T> node)
        {
            if (node.Values.Count != 1 || node.Neighbors.Count != 2)
            {
                throw new NotImplementedException();
            }

            T   nodeData  = node.Values[0];
            var rightNode = (_23TreeNode <T>)node.Neighbors[1];
            var leftNode  = (_23TreeNode <T>)node.Neighbors[0];

            rightNode.Parent = this;
            leftNode.Parent  = this;
            for (int m = 0; m < this.Values.Count; m++)
            {
                int result = this._comparer.Compare(this.Values[m], nodeData);
                if (result > 0)
                {
                    if (this.IsFull)
                    {
                        this.Values.Insert(m, nodeData);
                        this.Neighbors.RemoveAt(m);
                        this.Neighbors.Insert(m, rightNode);
                        this.Neighbors.Insert(m, leftNode);

                        return(this.Split());
                    }

                    this.Values.Insert(m, nodeData);
                    this.Neighbors.RemoveAt(m);
                    this.Neighbors.Insert(m, rightNode);
                    this.Neighbors.Insert(m, leftNode);
                    break;
                }

                if (m + 1 == this.Values.Count)
                {
                    if (this.IsFull)
                    {
                        this.Values.Add(nodeData);
                        this.Neighbors.RemoveAt(m + 1);
                        this.Neighbors.Add(leftNode);
                        this.Neighbors.Add(rightNode);

                        return(this.Split());
                    }

                    this.Values.Add(nodeData);
                    this.Neighbors.RemoveAt(m + 1);
                    this.Neighbors.Add(leftNode);
                    this.Neighbors.Add(rightNode);
                    break;
                }
            }

            return(this);
        }
Example #4
0
        /// <summary>
        /// Splits node regarding input element.
        /// </summary>
        /// <param name="data">
        /// Element to be inserted.
        /// </param>
        public _23TreeNode <T> Split(T data)
        {
            T   centerData;
            var leftData   = new List <T>();
            var rightData  = new List <T>();
            int zeroResult = this._comparer.Compare(this.Values[0], data);
            int oneResult  = this._comparer.Compare(this.Values[1], data);

            if (zeroResult > 0)
            {
                leftData.Add(data);
                centerData = this.Values[0];
                rightData.Add(this.Values[1]);
            }
            else if (oneResult > 0)
            {
                leftData.Add(this.Values[0]);
                centerData = data;
                rightData.Add(this.Values[1]);
            }
            else
            {
                leftData.Add(this.Values[0]);
                centerData = this.Values[1];
                rightData.Add(data);
            }

            this.Values.Clear();
            var leftNode  = new _23TreeNode <T>((_23TreeNode <T>) this.Parent, leftData);
            var rightNode = new _23TreeNode <T>((_23TreeNode <T>) this.Parent, rightData);

            var centerDataList = new List <T> {
                centerData
            };
            var children = new NodeList <T>(0)
            {
                leftNode, rightNode
            };
            var centerNode = new _23TreeNode <T>(null, centerDataList, children)
            {
                IsLeaf = false
            };

            if (this._parent != null)
            {
                leftNode.Parent     = this._parent;
                rightNode.Parent    = this._parent;
                this._parent.IsLeaf = false;
                this._parent        = this._parent.Add(centerNode);
                return(this._parent);
            }

            leftNode.Parent  = centerNode;
            rightNode.Parent = centerNode;
            return(centerNode);
        }
Example #5
0
        /// <summary>
        /// Splits node.
        /// </summary>
        public _23TreeNode <T> Split()
        {
            var leftData = new List <T>();
            var rightData = new List <T>();
            var leftNeighbors = new NodeList <T>(0);
            var rightNeighbors = new NodeList <T>(0);
            int i, j;

            for (i = 0; i < this.Values.Count / 2; i++)
            {
                leftData.Add(this.Values[i]);
                leftNeighbors.Add(this.Neighbors[i]);
            }

            T centerData = this.Values[i];

            leftNeighbors.Add(this.Neighbors[i]);
            for (j = ++i; j < this.Values.Count; j++)
            {
                rightData.Add(this.Values[j]);
                rightNeighbors.Add(this.Neighbors[j]);
            }

            rightNeighbors.Add(this.Neighbors[j]);

            this.Values.Clear();
            var leftNode = new _23TreeNode <T>((_23TreeNode <T>) this.Parent, leftData, leftNeighbors)
            {
                IsLeaf = false
            };
            var rightNode = new _23TreeNode <T>((_23TreeNode <T>) this.Parent, rightData, rightNeighbors)
            {
                IsLeaf = false
            };

            var centerDataList = new List <T> {
                centerData
            };
            var children = new NodeList <T>(0)
            {
                leftNode, rightNode
            };
            var centerNode = new _23TreeNode <T>(null, centerDataList, children)
            {
                IsLeaf = false
            };

            if (this._parent != null)
            {
                this._parent.IsLeaf = false;
                this._parent        = this._parent.Add(centerNode);
                return(this._parent);
            }

            return(centerNode);
        }
Example #6
0
 /// <summary>
 /// Initializes a new instance of the <see cref="_23TreeNode{T}"/> class.
 /// Constructor.
 /// </summary>
 /// <param name="parent">
 /// Parent node.
 /// </param>
 /// <param name="data">
 /// Values for the node.
 /// </param>
 /// <param name="children">
 /// Child nodes.
 /// </param>
 public _23TreeNode(_23TreeNode <T> parent, List <T> data, NodeList <T> children)
 {
     this._parent   = parent;
     this.Values    = data;
     this.Neighbors = children;
     this._isLeaf   = true;
     foreach (Node <T> t in this.Neighbors)
     {
         t.Parent = this;
     }
 }
Example #7
0
        /// <summary>
        /// Indicates whether tree contains element.
        /// </summary>
        /// <param name="data">
        /// Element to be searched.
        /// </param>
        /// <returns>
        /// </returns>
        public override SearchResult Contains(T data)
        {
            SearchResult searchResult;

            searchResult.SearchPath   = new List <int>();
            searchResult.NodesVisited = 0;
            _23TreeNode <T> current = this._root;

            while (current != null)
            {
                searchResult.NodesVisited++;
                for (int i = 0; i < current.Values.Count; i++)
                {
                    int result = this._comparer.Compare(current.Values[i], data);
                    if (result == 0)
                    {
                        return(searchResult);
                    }

                    if (result > 0)
                    {
                        if (current.Neighbors == null)
                        {
                            searchResult.SearchPath = null;

                            return(searchResult);
                        }

                        current = (_23TreeNode <T>)current.Neighbors[i];
                        searchResult.SearchPath.Add(i);
                        break;
                    }

                    if (i + 1 == current.Values.Count)
                    {
                        if (current.Neighbors == null)
                        {
                            searchResult.SearchPath = null;

                            return(searchResult);
                        }

                        current = (_23TreeNode <T>)current.Neighbors[i + 1];
                        searchResult.SearchPath.Add(i + 1);
                        break;
                    }
                }
            }
            searchResult.SearchPath = null;

            return(searchResult);
        }
Example #8
0
        /// <summary>
        /// Adds element to the tree.
        /// </summary>
        /// <param name="data">
        /// Element to be added.
        /// </param>
        public override void Add(T data)
        {
            if (this._root == null)
            {
                var dataList = new List <T> {
                    data
                };
                var node = new _23TreeNode <T>(null, dataList);
                this._root = node;
            }
            else
            {
                _23TreeNode <T> node = this.Insert(this._root, data);
                while (node.Parent != null)
                {
                    node = (_23TreeNode <T>)node.Parent;
                }

                this._root = node;
            }
        }
Example #9
0
        /// <summary>
        /// Deletes element in i-th position.
        /// </summary>
        /// <param name="data">
        /// Element to be deleted.
        /// </param>
        /// <param name="index">
        /// Position index.
        /// </param>
        public _23TreeNode <T> Delete(T data, int index)
        {
            if (this.IsLeaf)
            {
                if (!this.IsHalf)
                {
                    this.Values.RemoveAt(index);
                    return(this);
                }

                if (this._parent == null)
                {
                    this.Values.RemoveAt(index);
                    return(this);
                }

                this.Values.Remove(data);
                return(this.Merge());
            }

            // Find successor.
            _23TreeNode <T> successorNode = null;

            for (int i = 0; i < this.Values.Count; i++)
            {
                int result = this._comparer.Compare(this.Values[i], data);
                if (result <= 0)
                {
                    successorNode = (_23TreeNode <T>) this.Neighbors[i + 1];
                }
            }

            while (successorNode.Neighbors != null)
            {
                successorNode = (_23TreeNode <T>)successorNode.Neighbors[0];
            }

            this.Values[index] = successorNode.Values[0];
            return(successorNode.Delete(this.Values[index], 0));
        }
Example #10
0
        /// <summary>
        /// Inserts data into given node.
        /// </summary>
        /// <param name="node">
        /// Node in which element will be added.
        /// </param>
        /// <param name="data">
        /// Element to be added.
        /// </param>
        /// <returns>
        /// </returns>
        private _23TreeNode <T> Insert(_23TreeNode <T> node, T data)
        {
            if (!node.IsLeaf)
            {
                // Look for child to go to
                for (int i = 0; i < node.Values.Count; i++)
                {
                    int result = this._comparer.Compare(node.Values[i], data);
                    if (result > 0)
                    {
                        return(this.Insert(node.ChildAt(i), data));
                    }

                    if (i + 1 == node.Values.Count)
                    {
                        return(this.Insert(node.ChildAt(i + 1), data));
                    }
                }

                return(null);
            }

            if (!node.IsFull)
            {
                return(node.Add(data));
            }

            // return node.Split(data);
            if (node == this._root)
            {
                this._root = node.Split(data);
                return(this._root);
            }

            node.Parent = node.Split(data);
            return((_23TreeNode <T>)node.Parent);
        }
Example #11
0
        /// <summary>
        /// Deletes data from given node.
        /// </summary>
        /// <param name="node">
        /// Node from which element will be removed.
        /// </param>
        /// <param name="data">
        /// Element to be removed.
        /// </param>
        /// <returns>
        /// </returns>
        private _23TreeNode <T> Delete(_23TreeNode <T> node, T data)
        {
            while (node != null)
            {
                for (int i = 0; i < node.Values.Count; i++)
                {
                    int result = this._comparer.Compare(node.Values[i], data);
                    if (result == 0)
                    {
                        return(node.Delete(data, i));
                    }

                    if (result > 0)
                    {
                        if (node.Neighbors == null)
                        {
                            return(null);
                        }

                        return(this.Delete((_23TreeNode <T>)node.Neighbors[i], data));
                    }

                    if (i + 1 == node.Values.Count)
                    {
                        if (node.Neighbors == null)
                        {
                            return(null);
                        }

                        return(this.Delete((_23TreeNode <T>)node.Neighbors[i + 1], data));
                    }
                }
            }

            return(null);
        }
Example #12
0
        /// <summary>
        /// Merge node.
        /// </summary>
        public _23TreeNode <T> Merge()
        {
            _23TreeNode <T> left    = null;
            _23TreeNode <T> right   = null;
            int             myIndex = -1;

            // Get right and left sibling.
            for (int i = 0; i < this._parent.Neighbors.Count; i++)
            {
                if (this._parent.Neighbors[i] == this)
                {
                    myIndex = i;
                    if (i > 0)
                    {
                        left = (_23TreeNode <T>) this._parent.Neighbors[i - 1];
                    }

                    if (i + 1 < this._parent.Neighbors.Count)
                    {
                        right = (_23TreeNode <T>) this._parent.Neighbors[i + 1];
                    }
                }
            }

            // If it is the only child.
            if (myIndex == -1 || (left == null && right == null))
            {
                return(this);
            }

            // If it has right sibling.
            if (right != null)
            {
                if (!right.IsHalf)
                {
                    // Borrow from right.
                    this.Values.Add(this._parent.Values[myIndex]);
                    T borrowed = right.Values[0];
                    this._parent.Values[myIndex] = borrowed;
                    right.Values.Remove(borrowed);
                    if (right.Neighbors != null)
                    {
                        this.Neighbors.Add(right.Neighbors[0]);
                        right.Neighbors[0].Parent = this;
                        right.Neighbors.RemoveAt(0);
                    }
                }
                else
                {
                    // Merge with right
                    T fromParent = this._parent.Values[myIndex];
                    this.Values.Add(fromParent);
                    for (int i = 0; i < right.Values.Count; i++)
                    {
                        this.Values.Add(right.Values[i]);
                    }

                    if (right.Neighbors != null)
                    {
                        for (int j = 0; j < right.Neighbors.Count; j++)
                        {
                            this.Neighbors.Add(right.Neighbors[j]);
                            right.Neighbors[j].Parent = this;
                        }
                    }

                    this._parent.Neighbors.Remove(right);
                    this._parent.Values.Remove(fromParent);
                }
            }
            else
            {
                if (!left.IsHalf)
                {
                    // Borrow from left.
                    this.Values.Insert(0, this._parent.Values[myIndex - 1]);
                    T borrowed = left.Values[left.Values.Count - 1];
                    this._parent.Values[myIndex - 1] = borrowed;
                    left.Values.Remove(borrowed);
                    if (left.Neighbors != null)
                    {
                        this.Neighbors.Add(left.Neighbors[left.Neighbors.Count - 1]);
                        left.Neighbors[left.Neighbors.Count - 1].Parent = this;
                        left.Neighbors.RemoveAt(left.Neighbors.Count - 1);
                    }
                }
                else
                {
                    // Merge with left
                    T fromParent = this._parent.Values[myIndex - 1];
                    left.Values.Add(fromParent);
                    for (int i = 0; i < this.Values.Count; i++)
                    {
                        left.Values.Add(this.Values[i]);
                    }

                    if (this.Neighbors != null)
                    {
                        for (int j = 0; j < this.Neighbors.Count; j++)
                        {
                            left.Neighbors.Add(this.Neighbors[j]);
                            this.Neighbors[j].Parent = this;
                        }
                    }

                    this._parent.Neighbors.Remove(this);
                    this._parent.Values.Remove(fromParent);
                }
            }

            if (this._parent.IsDeficient && this._parent.Parent != null)
            {
                return(this._parent.Merge());
            }

            if (this._parent.Parent == null && (this._parent.Values == null || this._parent.Values.Count == 0))
            {
                this.Parent = null;
            }

            return(this);
        }
Example #13
0
 /// <summary>
 /// Initializes a new instance of the <see cref="_23Tree{T}"/> class.
 /// </summary>
 public _23Tree()
 {
     this._root = null;
 }
Example #14
0
 /// <summary>
 /// Clears nodes of the tree.
 /// </summary>
 public override void Clear()
 {
     this._root = null;
 }