Esempio n. 1
0
        /// <summary>
        /// 二叉排序树查找
        /// 实现思路:
        /// 从根节点开始遍历,如果正好该根节点就是要找的值,则返回true,如果要查找的值比根节点大,则调整到右子树查找,反之调整到左子树。
        /// </summary>
        /// <param name="bTree"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        public static bool BiSortTreeSearch(BiTree <int> bTree, int key)
        {
            Node <int> p;

            //如果树为空,则直接返回-1
            if (bTree.IsEmpty())
            {
                return(false);
            }

            p = bTree.Root;

            while (p != null)
            {
                //如果根节点就是要找的
                if (p.Data == key)
                {
                    return(true);
                }
                else if (key > p.Data)
                {
                    //调整到右子树
                    p = p.RChild;
                }
                else
                {
                    //调整到左子树
                    p = p.LChild;
                }
            }
            return(false);
        }
Esempio n. 2
0
        /// <summary>
        /// 删除二叉排序树的节点
        /// 这也是动态查询的一种情况,找到需要的节点后,如果存在,则删除该节点。
        /// 可以分为几下四种情况:
        ///     a.待删除的节点,本身就是叶节点:这种情况下最简单,只要把这个节点删除掉,然后父节点的LChild或RChild设置为null即可
        ///     b.待删除的节点,只有左子树:将本节点的左子树上移,挂到父节点下的LChild,然后删除自身即可
        ///     c.待删除的节点,只有右子树:将自身节点的右子树挂到父节点的左子树,然后删除自身即可
        ///     d.待删除的节点,左、右子树都有:这个要复杂一些,先找出自身节点右子树中的左分支的最后一个节点(最小左节点),然后将它跟自身对调,同时将“最小左节点”下的分支上移。
        /// </summary>
        /// <param name="tree"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        public static bool DeleteBiSort(BiTree <int> tree, int key)
        {
            //二叉排序树为空
            if (tree.IsEmpty())
            {
                return(false);
            }

            Node <int> p      = tree.Root;
            Node <int> parent = p;

            while (p != null)
            {
                if (p.Data == key)
                {
                    if (tree.IsLeaf(p))//如果待删除的节点为叶节点
                    {
                        #region
                        if (p == tree.Root)
                        {
                            tree.Root = null;
                        }
                        else if (p == parent.LChild)
                        {
                            parent.LChild = null;
                        }
                        else
                        {
                            parent.RChild = null;
                        }
                        #endregion
                    }
                    else if ((p.RChild == null) && (p.LChild != null)) //仅有左分支
                    {
                        #region
                        if (p == parent.LChild)
                        {
                            parent.LChild = p.LChild;
                        }
                        else
                        {
                            parent.RChild = p.LChild;
                        }
                        #endregion
                    }
                    else if ((p.LChild == null) && (p.RChild != null)) //仅有右分支
                    {
                        #region
                        if (p == parent.LChild)
                        {
                            parent.LChild = p.RChild;
                        }
                        else
                        {
                            parent.RChild = p.RChild;
                        }
                        #endregion
                    }
                    else //左,右分支都有
                    {
                        //原理:先找到本节点右子树中的最小节点(即右子树的最后一个左子节点)
                        #region
                        Node <int> q = p;
                        Node <int> s = p.RChild;
                        while (s.LChild != null)
                        {
                            q = s;
                            s = s.LChild;
                        }
                        Console.WriteLine("s.Data=" + s.Data + ",p.Data=" + p.Data + ",q.Data=" + q.Data);

                        //然后将找到的最小节点与自己对调(因为最小节点是从右子树中找到的,所以其值肯定比本身要大)
                        p.Data = s.Data;


                        if (q != p)
                        {
                            //将q节点原来的右子树挂左边(这样最后一个节点的子树就调整到位了)
                            q.LChild = s.RChild;
                        }
                        else //s节点的父节点就是p时,将s节点原来的右树向上提(因为s已经换成p点的位置了,所以这个位置就不需要了,直接把它的右树向上提升即可)
                        {
                            q.RChild = s.RChild;
                        }
                        #endregion
                    }
                    return(true);
                }
                else if (key > p.Data)
                {
                    parent = p;
                    p      = p.RChild;
                }
                else
                {
                    parent = p;
                    p      = p.LChild;
                }
            }
            return(false);
        }