C#算法-二叉树(创建、打印和删除节点)

今天学了二叉树,记录一下,直接上代码:

using System;

namespace 二叉树作业
{
    class Program
    {
        static void Main(string[] args)
        {
            BinaryTree<string> binaryTree = new BinaryTree<string>();
            binaryTree.Add("1");
            binaryTree.Add("3");
            binaryTree.Add("6");
            binaryTree.Add("4");
            binaryTree.Add("5");
            binaryTree.PrintAll();

            Console.WriteLine();

            binaryTree.Remove("1");
            binaryTree.PrintAll();
        }
    }

    class BinaryTree<T> where T : IComparable //构建泛型二叉树
    {
        class Node//内部定义一个节点类
        {
            public T _value;
            public Node _left;
            public Node _right;

            public Node(T value)
            {
                this._value = value;
            }//节点的构造器
        }

        Node root;//定义一个根节点

        public void Add(T value)
        {
            Add(ref root, value);
        }//添加元素的外部使用方法,内部调用,把根节点传进去
         //这里要注意根节点 root 的指向问题,因为是引用类型,传参时要加 ref 

        private void Add(ref Node node, T value)
        {
            if (node == null)
            {
                node = new Node(value);
            }//如果第一个节点就是空节点,直接 new 一个新节点把值放上去
            else
            {
                if (value.CompareTo(node._value) < 0)
                {
                    Add(ref node._left, value);
                }//如果要传进去值小于根节点的值,往左边放
                else
                {
                    Add(ref node._right, value);
                }//如果要传进去值大于根节点的值,往右边放
            }
        }//添加元素的内部实现方法

        public void PrintAll()
        {
            Print(root);
        }//打印的外部调用方法

        private void Print(Node node)
        {
            if (node != null)
            {
                Print(node._left);
                Console.Write(" " + node._value);
                Print(node._right);
            }
        }//打印的内部实现方法,中序遍历(左 -> 根 -> 右)


       public void Remove(T value)
        {
            Remove(ref root, value);
        }//删除节点的外部调用方法

         //删除的操作略复杂,要分四种大的情况判断,我这里是用递归的方法做的

        
        private void Remove(ref Node node,T value)
        {
            if(node == null)
            {
                Console.WriteLine($"没有{value}这个元素");
                return;
            }//如果这个节点指向空,那代表没有这个元素,直接返回

            if (value.CompareTo(node._value) < 0)
            {
                Remove(ref node._left, value);
            }//如果要删除的元素更小,从左子树删除

            else if (value.CompareTo(node._value) > 0)
            {
                Remove(ref node._right, value);
            }//如果要删除的元素更大,从右子树删除

            else//相等的情况下,要分开判断,从哪边开始操作
            {
                if(node._left == null && node._right == null)
                {
                    node = null;
                }//如果要删除的元素的左右节点都为空,直接把这个节点指向空即可

                else if(node._left != null && node._right != null)
                {
                    Node minNode = FindMin(node._right);
                    node._value = minNode._value;
                    Remove(ref node._right, minNode._value);
                }

                 //如果要删除的元素的左右节点都不为空(是最复杂的情况)
                 //我这边是的处理方法是 找这个要删除的元素的右节点 往下的最小值的节点也就是
                 //把 这个元素 右节点的左节点的值,拿上来充当这个元素
                 //再把这个被拿上来的元素递归删除

                 //(确实有点复杂,做的时候还是理解的,过两天就不一定了!哈哈...)

                else
                {
                    if(node._left == null)
                    {
                        node = node._right;
                    }
                    else
                    {
                        node = node._left;
                    }
                }
                //另外的情况就比较简单的了,如果要删除的元素有一边的节点不为空
                //如果它的左节点为空,那么把右节点提上来
                //如果它的右节点为空,那么把左节点拿上来
            }
        }//删除节点的内部实现方法

        private Node FindMin(Node node)
        {
            while (node._left != null)
            {
                node = node._left;
            }
            return node;
        }
         //找最小节点的方法,找这个要删除的元素的右节点 往下的最小值的节点 也就是
         //把 这个元素 右节点的左节点的值,拿上来充当这个元素,
    }
}

Guess you like

Origin blog.csdn.net/Erenlui/article/details/121845162