/// <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); }
/// <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); }