C#二叉排序树

88 阅读2分钟

二叉排序树

二叉排序树,又称二叉查找树。它可以是一颗空树,也可以是具有以下性质的二叉树。

  • 若它的左子树不为空,则左子树上的所有结点的值都小于根节点的值
  • 若它的右子树不为空,则右子树上的所有结点的值都大于根结点的值

1695280528634.png

二叉排序树的优点:

  • 排序方便
  • 方便查找
  • 方便插入和删除

二叉排序树增删查的代码实现

public class BSNode
    {
        public BSNode LeftChild { get; set; }
        public BSNode RightChild { get; set; }
        public BSNode Parent { get; set; }
        public int Data { get; set; }

        public BSNode()
        {
            
        }

        public BSNode(int item)
        {
            this.Data = item;
        }
    }
public class BSTree
    {
        BSNode root = null;

        public void Add(int item)
        {
            BSNode newNode = new BSNode(item);
            if (root == null)
            {
                root = newNode;
            }
            else
            {
                BSNode temp = root;
                while (true)
                {
                    if (item >= temp.Data)//放在temp的右边
                    {
                        if (temp.RightChild == null)
                        {
                            temp.RightChild = newNode;
                            newNode.Parent = temp;
                            break;
                        }
                        else
                        {
                            temp = temp.RightChild;
                        }
                    }
                    else //放在temp左边
                    {
                        if (temp.LeftChild == null)
                        {
                            temp.LeftChild = newNode;
                            newNode.Parent = temp;
                            break;
                        }
                        else
                        {
                            temp = temp.LeftChild;
                        }
                    }
                }
            }
        }

        public void MiddleTraversal()
        {
            MiddleTraversal(root);
        }

        private void MiddleTraversal(BSNode node)
        {
            if(node == null) return;
            
            MiddleTraversal(node.LeftChild);
            Console.Write(node.Data + " ");
            MiddleTraversal(node.RightChild);
        }

        public bool Find(int item)
        {
            //return Find(item, root);
            BSNode temp = root;
            while (true)
            {
                if (temp == null) return false;
                if (temp.Data == item) return true;
                if (item > temp.Data)
                    temp = temp.RightChild;
                else
                    temp = temp.LeftChild;
            }
        }
        private bool Find(int item, BSNode node)
        {
            if (node == null) return false;
            if (node.Data == item)
            {
                return true;
            }
            else
            {
                /*if (Find(item, node.LeftChild))
                {
                    return true;
                }

                if (Find(item, node.RightChild))
                {
                    return true;
                }*/
                if (item > node.Data)
                {
                    return Find(item, node.RightChild);
                }
                else
                {
                    return Find(item, node.LeftChild);
                }
            }
        }

        public bool Delete(int item)
        {
            BSNode temp = root;
            while (true)
            {
                if (temp == null) return false;
                if (temp.Data == item)
                {
                    Delete(temp);
                    return true;
                }
                if (item > temp.Data)
                    temp = temp.RightChild;
                else
                    temp = temp.LeftChild;
            }
        }
        public void Delete(BSNode node)
        {
            //删除结点为叶子结点的情况
            if (node.LeftChild == null && node.RightChild == null)
            {
                if (node.Parent == null)//删除结点为根节点
                {
                    root = null;
                }
                else if (node.Parent.LeftChild == node)//删除结点为父结点的左子节点
                {
                    node.Parent.LeftChild = null;
                }
                else if (node.Parent.RightChild == node)//删除结点为父结点的右子结点
                {
                    node.Parent.RightChild = null;
                }
                return;
            }
            
            //删除结点只有右子树的情况
            if (node.LeftChild == null&& node.RightChild != null)
            {
                node.Data = node.RightChild.Data;
                node.RightChild = null;
                return;
            }
            //删除结点只有左子树的情况
            if (node.RightChild == null && node.LeftChild != null)
            {
                node.Data = node.LeftChild.Data;
                node.LeftChild = null;
                return;
            }
            
            //删除结点既有左子树又有右子树的情况
            //从该节点的右子树中找到最小的
            BSNode temp = node.RightChild;
            while (true)
            {
                if (temp.LeftChild != null)
                {
                    temp = temp.LeftChild;
                }
                else
                {
                    break;
                }
            }
            //循环结束后temp则为右子树中最小的
            //将该结点的值赋给被删除的结点
            node.Data = temp.Data;
            //递归删除掉最小的这个结点
            Delete(temp);
        }
    }