二叉树算法,

 

顺序确定的, 小的放在左边,大的放在右边。

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace BineryTree
{
    class Program
    {
        static void Main(string[] args)
        {
            Tree<int> tree = new Tree<int>(55);          
            tree.Insert(33);
            tree.Insert(34);
            tree.Insert(32);
            tree.Insert(45);
            tree.Insert(67);
            tree.Insert(65);
            tree.Insert(56);
            tree.Insert(66);
            tree.Insert(68);
            tree.Insert(69);


            tree.MiddleOrder(tree);
            Console.WriteLine();
            Console.WriteLine("Max:" + tree.FindMax());
            Console.WriteLine("Min:" + tree.FindMin());
            var tree1 = tree.FindTree(67);
            if (tree1 != null)
            {
                tree1.MiddleOrder(tree1);
            }
            Console.WriteLine();
            var root = tree.Delete(34);
            tree.MiddleOrder(root);

            Console.Read();
        }
    }

    public class Tree<T> where T : IComparable<T>
    {
        /// <summary>
        /// Current node
        /// </summary>
        public T NodeData { get; set; }

        /// <summary>
        /// Left Node
        /// </summary>
        public Tree<T> LeftNode { get; set; }

        /// <summary>
        /// Right Node
        /// </summary>
        public Tree<T> RightNode { get; set; }

        public Tree(T node)
        {
            NodeData = node;
        }

        public void Insert(T node)
        {
            T currentNode = NodeData;

            if (currentNode.CompareTo(node) > 0)
            {
                if (LeftNode == null)
                {
                    LeftNode = new Tree<T>(node);
                }
                else
                {
                    LeftNode.Insert(node);
                }
            }
            else
            {
                if (RightNode == null)
                {
                    RightNode = new Tree<T>(node);
                }
                else
                {
                    RightNode.Insert(node);
                }
            }
        }

        /// <summary>
        /// 前序遍历,也叫先根遍历,遍历的顺序是,根,左子树,右子树
        /// </summary>
        /// <param name="root"></param>
        public void PreOrder(Tree<T> root)
        {
            if (root != null)
            {
                Console.Write(root.NodeData + " ");
                PreOrder(root.LeftNode);
                PreOrder(root.RightNode);
            }
        }

        /// <summary>
        /// 中序遍历,也叫中根遍历,顺序是 左子树,根,右子树
        /// </summary>
        /// <param name="root"></param>
        public void MiddleOrder(Tree<T> root)
        {
            if (root != null)
            {
                MiddleOrder(root.LeftNode);
                Console.Write(root.NodeData + " ");
                MiddleOrder(root.RightNode);
            }
        }

        /// <summary>
        /// 后序遍历,也叫后根遍历,遍历顺序,左子树,右子树,根
        /// </summary>
        /// <param name="root"></param>
        public void PostOrder(Tree<T> root)
        {
            if (root != null)
            {
                PostOrder(root.LeftNode);
                PostOrder(root.RightNode);
                Console.Write(root.NodeData + " ");
            }
        }

        /// <summary>
        /// 查找最大指
        /// </summary>
        /// <returns></returns>
        public T FindMax()
        {
            Tree<T> currentRoot = this;

            while (currentRoot.RightNode != null)
            {
                currentRoot = currentRoot.RightNode;
            }
            return currentRoot.NodeData;

        }

        /// <summary>
        /// 查找最小值
        /// </summary>
        /// <returns></returns>
        public T FindMin()
        {
            Tree<T> currentRoot = this;
            while (currentRoot.LeftNode != null)
            {
                currentRoot = currentRoot.LeftNode;
            }
            return currentRoot.NodeData;

        }

        public Tree<T> FindTree(T data)
        {
            Tree<T> currentRoot = this;
            while (true)
            {
                if (currentRoot.NodeData.CompareTo(data) > 0)
                {
                    if (currentRoot.LeftNode == null)
                        break;
                    currentRoot = currentRoot.LeftNode;
                }
                else if (currentRoot.NodeData.CompareTo(data) < 0)
                {
                    if (currentRoot.RightNode == null)
                        break;
                    currentRoot = currentRoot.RightNode;
                }
                else
                {
                    return currentRoot;
                }

            }

            if (currentRoot.NodeData.CompareTo(data) != 0)
            {
                return null;
            }

            return currentRoot;
        }

        public Tree<T> Delete(T data)
        {
            var rootNode = this;
            Tree<T> parent = this;
            Tree<T> current = this;
            while (true)
            {
                if (current.NodeData.CompareTo(data) > 0)
                {
                    if (current.LeftNode == null)
                        break;
                    parent = current;
                    current = current.LeftNode;
                }
                else if (current.NodeData.CompareTo(data) < 0)
                {
                    if (current.RightNode == null)
                        break;
                    parent = current;
                    current = current.RightNode;
                }
                else
                {
                   // parent = null;
                    break;
                }
            }
                //情况一:叶节点,直接删除
                if (current.LeftNode == null && current.RightNode == null)
                {
                    //如果被删节点是根节点,且没有左右孩子
                    if (current == rootNode && rootNode.LeftNode == null && rootNode.RightNode == null)
                    {
                        rootNode = null;
                    }
                    else if (current.NodeData.CompareTo(parent.NodeData) < 0)
                        parent.LeftNode = null;
                    else
                        parent.RightNode = null;
                }
                //情况二,所删节点只有左孩子节点时
                else if (current.LeftNode != null && current.RightNode == null)
                {
                    if (current.NodeData.CompareTo(parent.NodeData) < 0)
                        parent.LeftNode = current.LeftNode;
                    else
                        parent.RightNode = current.RightNode;


                }
                //情况三,所删节点只有右孩子节点时
                else if (current.LeftNode == null && current.RightNode != null)
                {
                    if (current.NodeData.CompareTo(parent.NodeData) < 0)
                        parent.LeftNode = current.RightNode;
                    else
                        parent.RightNode = current.RightNode;

                }
                //情况四,所删节点有左右两个孩子
                else
                {
                    //current是被删的节点,temp是被删左子树最右边的节点
                    Tree<T> temp;
                    //先判断是父节点的左孩子还是右孩子
                    if (current.NodeData.CompareTo(parent.NodeData) < 0)
                    {

                        parent.LeftNode = current.LeftNode;
                        temp = current.LeftNode;
                        //寻找被删除节点最深的右孩子
                        while (temp.RightNode != null)
                        {
                            temp = temp.RightNode;
                        }
                        temp.RightNode = current.RightNode;


                    }
                    //右孩子
                    else if (current.NodeData.CompareTo(parent.NodeData) > 0)
                    {
                        parent.RightNode = current.LeftNode;
                        temp = current.LeftNode;
                        //寻找被删除节点最深的左孩子
                        while (temp.RightNode != null)
                        {
                            temp = temp.RightNode;
                        }
                        temp.RightNode = current.RightNode;
                    }
                    //当被删节点是根节点,并且有两个孩子时
                    else
                    {
                        temp = current.LeftNode;
                        while (temp.RightNode != null)
                        {
                            temp = temp.RightNode;
                        }
                        temp.RightNode = rootNode.RightNode;
                        rootNode = current.LeftNode;
                    }

                }


            
            return rootNode;

        }

    }
}