C#二叉树学习总结2:标准的二叉查找树以及相关操作

上次对BinarySearchTree的总结不太常用,因为很多时候题目以及要求TreeNode的格式了,不能有parent节点,而且parent节点也会浪费一个空间,因而这里重新再写一遍更加标准的BST结构及其相应的操作。

    class Node
    {
        //一个标准的Node
        public int val;
        public Node lnode;
        public Node rnode;
        public Node(int val)
        {
            this.val = val;
        }
    }

下面是BST类,分别有增加节点,查找节点,中序遍历所有节点,删除某个节点等方法

 class BinarySearchTree
    {
        public Node rootNode;
        
        //增加节点
        public void AddNodeToTree(int val)
        {
            if(rootNode == null)
            {
                rootNode = new Node(val);
                return;
            }
            Node current = rootNode;
            while (true)
            {
                if (val < current.val)
                {
                    if (current.lnode == null)
                    {
                        current.lnode = new Node(val);
                        break;
                    }
                    current = current.lnode;
                }
                else
                {
                    if (current.rnode == null)
                    {
                        current.rnode = new Node(val);
                        break;
                    }
                    current = current.rnode;
                }
            }
        }

        //查找节点
        public bool FindNode(Node node,int val)
        {
            if(node == null)
            {
                return false;
            }
            if(node.val == val)
            {
                return true;
            }
            if(node.val > val)
            {
                return  FindNode(node.lnode, val);
            }
            else
            {
                return FindNode(node.rnode, val);
            }
        }

        //中序输出所有节点
        public void Inorder(Node theroot)
        {
            if (theroot != null)
            {
                Inorder(theroot.lnode);
                WriteLine(theroot.val);
                Inorder(theroot.rnode);
            }
        }
        
        //删除某个节点
        public bool DeleteNode(Node theRoot, int deleteVal)
        {
            //先找到该节点
            if(rootNode == null)
            {
                return false;
            }
            Node current = theRoot;
            Node parent = theRoot;
            bool isLeftChild = false;
            while(current.val != deleteVal)
            {
                parent = current;
                if(current.val < deleteVal)
                {
                    current = current.rnode;
                    isLeftChild = false;
                }
                else
                {
                    current = current.lnode;
                    isLeftChild = true;
                }
                if (current == null)
                {
                    return false;
                }
            }
            //退出循环时,current就是待删除的节点,parent是待删节点的父节点
            //下面分三种情况,进行分类处理

            //待删除的是叶子节点
            if(current.lnode == null && current.rnode == null)
            {
                if (isLeftChild) parent.lnode = null;
                else
                {
                    parent.rnode = null;
                }
            }
            else if(current.lnode != null && current.rnode == null)
            {
                //左右左子树没有右子树
                if (isLeftChild)
                {
                    parent.lnode = parent.lnode.lnode;
                }
                else
                {
                    parent.rnode = parent.rnode.lnode;
                }
            }
            else if(current.lnode == null && current.rnode != null)
            {
                //只有右子树没有左子树
                if (isLeftChild)
                {
                    parent.lnode = parent.lnode.rnode;
                }
                else
                {
                    parent.rnode = parent.rnode.rnode;
                }
            }
            else
            {
                //待删除的节点左右子树都有
                Node replace = current.rnode;
                while(replace.lnode != null)
                {
                    replace = replace.rnode.lnode;
                }
                DeleteNode(rootNode, replace.val);
                current.val = replace.val;
            }
            return true;
        }
    }

注意在删除节点那里涉及树的重构因而分为三种不同的方法。注意在判断current==null的情况需要在current等于其左右节点之后判断。

需要多练习才能熟练操作。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值