Esempio n. 1
0
        /// <summary>
        ///? 层次遍历
        /// </summary>
        public IEnumerable <T> LevelTravesal(BinTreeNode <T> node)
        {
            var nodeQueue  = new Queue <BinTreeNode <T> >();
            var returnList = new List <T>();

            nodeQueue.Enqueue(node);
            while (nodeQueue.Count > 0)
            {
                node = nodeQueue.Dequeue();
                if (node != null)
                {
                    returnList.Add(node.value);
                }
                if (node.left != null)
                {
                    nodeQueue.Enqueue(node.left);
                }
                if (node.right != null)
                {
                    nodeQueue.Enqueue(node.right);
                }
            }

            return(returnList);
        }
Esempio n. 2
0
 /// <summary>
 ///? 如果目标有空子节点,则设置为父亲
 /// </summary>
 public bool SetNewParent(BinTreeNode <T> parent)
 {
     if (parent == null && this.parent == null)
     {
         return(false);
     }
     if (parent == null && this.parent != null)
     {
         ClearSelf();
         return(false);
     }
     //插入到左
     if (parent.left == null)
     {
         parent.left = this;
         this.parent = parent;
         return(true);
     }
     //插入到右
     if (parent.right == null)
     {
         parent.right = this;
         this.parent  = parent;
         return(true);
     }
     //节点已满,插入失败
     return(false);
 }
Esempio n. 3
0
        /// <summary>
        ///? 从根节点开始的 先父 次左 后右 的链式的插入很麻烦
        /// </summary>
        private bool InsertPLR(BinTreeNode <T> parent, BinTreeNode <T> newNode, ref Queue <BinTreeNode <T> > nodeQueue)
        {
            var insertResult = false;

            nodeQueue.Enqueue(parent.left);
            nodeQueue.Enqueue(parent.right);

            //! 尝试插入
            insertResult = newNode.SetNewParent(parent); //尝试插入到parent,调用node中的SetParent
            if (insertResult == true)
            {
                return(true);
            }
            //! 插入失败,则尝试插入其子节点
            else
            {
                while (!insertResult)
                {
                    var toInsertNode = nodeQueue.Dequeue();
                    //递归调用 尝试插入节点,调用node中的SetParent
                    insertResult = InsertPLR(toInsertNode, newNode, ref nodeQueue);
                }
                return(insertResult);
            }
        }
Esempio n. 4
0
        /// <summary>
        ///? 中序遍历 L-P-R
        /// </summary>
        public IEnumerable <T> InTraversal(BinTreeNode <T> node)
        {
            var nodeStack  = new Stack <BinTreeNode <T> >();
            var nodeList   = new List <BinTreeNode <T> >();
            var returnList = new List <T>();

            while (true)
            {
                // 沿着左路一直走到底,沿途添加node到stack中
                InTraverAlongLeft(node, ref nodeStack);
                // 如果stack中没有元素,跳出循环
                if (nodeStack.Count <= 0)
                {
                    break;
                }
                node = nodeStack.Pop();
                // 如果左侧元素为空或者已经被访问,则访问该元素,否则将TraverAlongLeft
                if (node.left == null || node.left.isVisited)
                {
                    InTraverVisit(node, ref nodeStack, ref nodeList);
                }
            }
            foreach (var item in nodeList)
            {
                item.isVisited = false;
                returnList.Add(item.value);
            }
            return(returnList);
        }
Esempio n. 5
0
        private void AutoBalance(BinTreeNode <T> node)
        {
            var grandPa = node.parent.parent;

            if (grandPa == null)
            {
                return;
            }
            else if (grandPa.left == null || grandPa.right == null)
            {
                //! 当grandpa有一个子节点为空
                //! 交换grandPa ,parent,node的值,node从parent的子节点变成grandpa的子节点
                var temp = grandPa.value;
                grandPa.value = node.parent.value;

                node.parent.value = node.value;
                node.parent.left  = null;
                node.parent.right = null;

                node.parent = grandPa;
                node.value  = temp;
                if (grandPa.left == null)
                {
                    grandPa.left = node;
                }
                if (grandPa.right == null)
                {
                    grandPa.right = node;
                }
                return;
            }
            AutoBalance(node.parent);
        }
Esempio n. 6
0
 public bool IsLeafNode => this.parent != null && this.left == null && this.right == null; //叶子节点
 public BinTreeNode(T value)
 {
     this.value  = value;
     this.parent = null;
     this.left   = null;
     this.right  = null;
     this.height = -1;
 }
Esempio n. 7
0
 private void InTraverVisit(
     BinTreeNode <T> node, ref Stack <BinTreeNode <T> > nodeStack, ref List <BinTreeNode <T> > nodeList)
 {
     if (node.right != null)
     {
         nodeStack.Push(node.right);
     }
     nodeList.Add(node);
     node.isVisited = true;
 }
Esempio n. 8
0
 private void PreTraverVisit(
     BinTreeNode <T> node, ref Stack <BinTreeNode <T> > nodeStack)
 {
     if (node.right != null)
     {
         nodeStack.Push(node.right);
     }
     if (node.left != null)
     {
         nodeStack.Push(node.left);
     }
 }
Esempio n. 9
0
 /// <summary>
 ///? 清楚自身以及父节点中关于自身的信息
 /// </summary>
 public void ClearSelf()
 {
     if (this.parent.left == this)
     {
         this.parent.left = null;
     }
     if (this.parent.right == this)
     {
         this.parent.right = null;
     }
     this.parent = null;
 }
Esempio n. 10
0
        /// <summary>
        /// 添加值
        /// </summary>
        /// <param name="value"></param>
        public void Add(T value)
        {
            var newNode = CreateNewNode(value);

            if (_root == null)
            {
                _root = newNode;
            }
            else
            {
                CompareAndAdd(newNode, _root, false);
                AutoBalance(newNode);
            }
        }
Esempio n. 11
0
        /// <summary>
        ///? 更新高度
        /// </summary>
        protected void UpdateHeight(BinTreeNode <T> node)
        {
            if (node == null)
            {
                return;
            }
            var orignHeight = node.height;

            node.UpdateHeight();
            if (node.height != orignHeight)
            {
                UpdateHeight(node.parent);
            }
        }
Esempio n. 12
0
        /// <summary>
        ///? 先序遍历 P-L-R
        /// </summary>
        public IEnumerable <T> PreTraversal(BinTreeNode <T> node)
        {
            var nodeStack  = new Stack <BinTreeNode <T> >();
            var returnList = new List <T>();

            nodeStack.Push(node);
            while (nodeStack.Count > 0)
            {
                node = nodeStack.Pop();
                PreTraverVisit(node, ref nodeStack);
                returnList.Add(node.value);
            }
            return(returnList);
        }
Esempio n. 13
0
        protected BinTreeNode <T> SearchClosestBigger(BinTreeNode <T> node)
        {
            var bigger = node;

            if (bigger.right != null)
            {
                bigger = bigger.right;
            }
            //一直向左
            while (bigger.left != null)
            {
                bigger = bigger.left;
            }
            return(bigger);
        }
Esempio n. 14
0
        protected BinTreeNode <T> SearchClosestSmaller(BinTreeNode <T> node)
        {
            var smaller = node;

            if (smaller.left != null)
            {
                smaller = smaller.left;
            }
            //一直向左
            while (smaller.right != null)
            {
                smaller = smaller.right;
            }
            return(smaller);
        }
Esempio n. 15
0
 private void InTraverAlongLeft(BinTreeNode <T> node, ref Stack <BinTreeNode <T> > nodeStack)
 {
     while (node.isVisited == false)
     {
         nodeStack.Push(node);
         if (node.left != null && !node.left.isVisited)
         {
             node = node.left;
         }
         else
         {
             break;
         }
     }
 }
Esempio n. 16
0
        /// <summary>
        ///? 优先排满一层 的添加
        /// </summary>
        public virtual void Add(T value)
        {
            var newNode = new BinTreeNode <T>(value);

            if (_root == null)
            {
                _root = newNode;
            }
            else
            {
                InsertAtLastNearby(newNode);
            }
            ++_count;              // 数量增加
            _lastInsert = newNode; // 记录为最后一次插入的节点
            UpdateHeight(newNode); // 更新高度
        }
Esempio n. 17
0
        /// <summary>
        /// 添加值
        /// </summary>
        public override void Add(T value)
        {
            var newNode = new BinTreeNode <T>(value);
            var isAdded = false;

            if (_root == null)
            {
                _root   = newNode;
                isAdded = true;
            }
            else
            {
                isAdded = CompareAndAdd(newNode, _root, false);
            }
            //元素不重复,添加成功
            if (isAdded)
            {
                ++_count;              // 数量增加
                UpdateHeight(newNode); // 更新高度
            }
        }
Esempio n. 18
0
 private bool CompareAndAdd(
     BinTreeNode <T> newNode, BinTreeNode <T> originNode, bool isLeft)
 {
     if (originNode == null)
     {
         //! 如果节点为空,则为新节点的父亲的子节点赋值
         if (isLeft)
         {
             newNode.parent.left = newNode;
         }
         else
         {
             newNode.parent.right = newNode;
         }
         return(true);
     }
     else
     {
         //! 如果节点非空,节点为新节点的父亲
         newNode.parent = originNode;
         //! 比较大小,决定向左还是向右
         var compareResult = newNode.value.CompareTo(originNode.value);
         if (compareResult == 1)
         {
             // 如果大于,放右边
             return(CompareAndAdd(newNode, originNode.right, false));
         }
         else if (compareResult == 0)
         {
             newNode.ClearSelf();
             // 如果等于,不添加
             return(false);
         }
         else
         {
             // 如果小于,放左边
             return(CompareAndAdd(newNode, originNode.left, true));
         }
     }
 }
Esempio n. 19
0
        /// <summary>
        ///? 在最后一次插入节点的附近寻找空节点插入
        /// </summary>
        private void InsertAtLastNearby(BinTreeNode <T> newNode)
        {
            //! 上一次插入的节点可能被删除了
            var nodeQueue = new Queue <BinTreeNode <T> >();

            if (_lastInsert == null || _lastInsert == _root)
            {
                InsertPLR(_root, newNode, ref nodeQueue);
                return;
            }
            var toInsert = _lastInsert.GetSibling();

            //! toInsert 为空,可以插入
            if (toInsert == null)
            {
                InsertPLR(_lastInsert.parent, newNode, ref nodeQueue);
                return;
            }
            else
            {
                //! 上一次插入节点的父节点满了
                if (_lastInsert.parent.parent == null)
                {
                    InsertPLR(_root, newNode, ref nodeQueue);
                    return;
                }
                toInsert = _lastInsert.parent.GetSibling();
                if (toInsert == null)
                {
                    InsertPLR(_lastInsert.parent.parent, newNode, ref nodeQueue);
                    return;
                }
                else
                {
                    //! 上一次插入节点的兄弟节点也满了,不妨从根节点开始
                    InsertPLR(_root, newNode, ref nodeQueue);
                    return;
                }
            }
        }
Esempio n. 20
0
        private void GetCloseNumber(ref BinTreeNode <T> originNode)
        {
            var temp = originNode;

            if (originNode.right != null)
            {
                temp = originNode.right;
                while (temp.left != null)
                {
                    temp = temp.left;
                }
            }
            else if (originNode.left != null)
            {
                temp = originNode.left;
                while (temp.left != null)
                {
                    temp = temp.right;
                }
            }
            originNode.value = temp.value;
            // if (temp.parent.left == temp) temp.parent.left
        }
Esempio n. 21
0
        private BinTreeNode <T> CompareAndRemove(T value, ref BinTreeNode <T> node, bool isRemoving)
        {
            // 遇到空节点,结束 查询/移除 循环
            if (node == null)
            {
                return(null);
            }
            // 遇到等值节点,返回结果
            if (node.value.Equals(value))
            {
                // 是否是移除操作
                if (isRemoving)
                {
                    var temp = new BinTreeNode <T>(node.value);
                    if (node.IsLeafNode)
                    {
                        node.ClearSelf(); //如果为叶子节点,直接移除
                    }
                    else
                    {
                        var replace = SearchClosestBigger(node); //得到最近的点,优先选择较大的
                        if (replace == null)
                        {
                            replace = SearchClosestSmaller(node); //次选较小的
                        }
                        node.value = replace.value;               //替换值
                        // 如果是叶子节点,则移除并且从父节点开始更新高度;
                        if (replace.IsLeafNode)
                        {
                            var tempParent = replace.parent;
                            replace.ClearSelf(); //移除替换点
                            UpdateHeight(tempParent);
                        }
                        //如果不是叶子节点,则替换节点必定只有唯一子节点
                        //将其昨晚父节点的子节点,并更新高度
                        else
                        {
                            if (replace.left != null)
                            {
                                replace.parent.left = replace.left;
                                replace.left.parent = replace.parent.left;
                                UpdateHeight(replace.parent);
                                replace.ClearSelf();
                            }
                            else if (replace.right != null)
                            {
                                replace.parent.right = replace.right;
                                replace.right.parent = replace.parent.right;
                                UpdateHeight(replace.parent);
                                replace.ClearSelf();
                            }
                        }
                    }
                    return(temp);
                }
            }
            //! 比较大小,决定向左还是向右递归
            var compareResult = value.CompareTo(node.value);

            if (compareResult == 1)
            {
                // 如果大于,放右边
                return(CompareAndRemove(value, ref node.right, isRemoving));
            }
            else
            {
                // 如果小于等于,放左边
                return(CompareAndRemove(value, ref node.left, isRemoving));
            }
        }
Esempio n. 22
0
 public AVLTree()
 {
     _root = null;
 }
Esempio n. 23
0
        private BinTreeNode <T> CompareAndRemove(T value, ref BinTreeNode <T> originNode, bool isRemoving)
        {
            if (originNode == null)
            {
                return(null);                    //! 遇到空节点,结束 查询/移除 循环
            }
            if (originNode.value.Equals(value))
            {
                //! 遇到等值节点,结束 查询/移除 循环
                if (isRemoving)
                {
                    var temp  = new BinTreeNode <T>(originNode.value);
                    var tempp = originNode;
                    GetCloseNumber(ref originNode);

                    return(temp);
                    //TODO ZIG 旋转 // ZAG旋转 // ZIG-ZAG // ZAG-ZIG
                    //TODO RotateAT
                    //左侧不位空,赋予左侧值,清除左节点
                    // if (originNode.left != null) {
                    //     originNode.value = originNode.left.value;
                    //     originNode.left.ClearSelf();
                    //     //若右侧也不为空,则进行自动平衡修正
                    //     if (originNode.right != null)
                    //         AutoBalance(originNode.right);
                    //     return temp;
                    // }
                    // //右侧不位空,赋予右侧值,清除右节点
                    // else if (originNode.right != null) {
                    //     originNode.value = originNode.right.value;
                    //     originNode.right.ClearSelf();
                    //     var toBalance = originNode.right == null?originNode : originNode.right;
                    //     // if (originNode.left != null)
                    //     //     AutoBalance(originNode.left);
                    //     return temp;
                    // }
                    // //左右都为空,清除节点
                    // else {
                    //     originNode.ClearSelf();
                    //     return temp;
                    // }
                }
                else
                {
                    return(originNode);
                }
            }
            //! 比较大小,决定向左还是向右
            var compareResult = value.CompareTo(originNode.value);

            if (compareResult == 1)
            {
                // 如果大于,放右边
                return(CompareAndRemove(value, ref originNode.right, isRemoving));
            }
            else
            {
                // 如果小于等于,放左边
                return(CompareAndRemove(value, ref originNode.left, isRemoving));
            }
        }
Esempio n. 24
0
 private void PostTraverVisit(
     BinTreeNode <T> node, ref Stack <BinTreeNode <T> > nodeStack, ref List <BinTreeNode <T> > nodeList)
 {
     nodeList.Add(node);
     node.isVisited = true;
 }