二叉树的实现(C#)

直接上C#代码

/*
 * author:codingriver
 * 20181016 21:46
 */

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

namespace TreeTest
{

    /// <summary>
    /// 打印输出公共接口
    /// </summary>
    interface IPrint
    {
        void Print();
        void Write();

        string ToString();
    }


    class Tree<T> where T : IComparable<T>, IPrint
    {
        private Node<T>root;
        public Node<T> Root
        {
            get { return root; }
            set{root=value;}
        }

        /// <summary>
        /// 先序遍历(根节点-->左孩子-->右孩子)
        /// </summary>
        public void FrontRootOrder()
        {
            Root.FrontRootOrder();
        }

        /// <summary>
        /// 中序遍历(左孩子-->根节点-->右孩子)
        /// </summary>
        public void InRootOrder()
        {
            Root.InRootOrder();
        }

        /// <summary>
        /// 后序遍历(左孩子-->右孩子-->根节点)
        /// </summary>
        public void BackRootOrder()
        {
            Root.BackRootOrder();
        }

        public int Count()
        {
            return Count(Root);
        }
        //计算节点数
        public int Count(Node<T> node)
        {
            if (node == null) return 0;
            return Count(node.Left) + Count(node.Right) + 1;
        }

        public int Height()
        {
            return Height(Root);
        }
        //2、计算树的高度(后序遍历)
        public int Height(Node<T> node)
        {
            int a, b;
            if (node == null) return 0;
            a = Height(node.Left);
            b = Height(node.Right);
            if (a > b) return a + 1; else return b + 1;
        }

        /*二叉树遍历的应用*/
        //1、计算叶子节点的个数(先序遍历)
        //度为2的节点和度为0的节点也就是叶子节点的关系是n0=n2+1;加上可以统计节点的个数所以就可以
        //分别统计度为0、度为1和度为2的节点数了。
        public void CountLeaf(Node<T> node, ref int count)
        {
            if (node != null)
            {
                if ((node.Left == null) && (node.Right == null))
                    count++;
                CountLeaf(node.Left, ref count);
                CountLeaf(node.Right, ref count);
            }
        }


        /// <summary>
        /// 广度优先遍历(层序遍历)
        /// 
        /// </summary>
        public void LevelOrder()
        {
            Node<T> node = root;
            Queue<Node<T>> queue = new Queue<Node<T>>();
            queue.Enqueue(node);
            while (queue.Count > 0)
            {
                node = queue.Dequeue();
                node.Write();
                if (node.Left != null)
                {
                    queue.Enqueue(node.Left);

                }
                if (node.Right != null)
                {
                    queue.Enqueue(node.Right);
                }
            }
        }




        public void FontOrder()
        {

            Stack<Node<T>> stack = new Stack<Node<T>>();
            Node<T> node = Root;
            while(node!=null ||stack.Count>0)
            {
                node.Write();
                stack.Push(node);
                node = node.Left;

                while(node==null&&stack.Count>0)
                {
                    node = stack.Pop();
                    node = node.Right;

                }
            }
        }
        public void FontOrder1()
        {

            Stack<Node<T>> stack = new Stack<Node<T>>();
            Node<T> node = Root;
            while (node != null || stack.Count > 0)
            {
                if(node!=null)
                {
                    stack.Push(node);
                    node.Write();
                    node = node.Left;
                }
                else
                {
                    node = stack.Pop();
                    node = node.Right;
                }
            }
        }

        public void InOrder()
        {

            Stack<Node<T>> stack = new Stack<Node<T>>();
            Node<T> node = Root;
            while (node != null || stack.Count > 0)
            {
                stack.Push(node);
                node = node.Left;

                while (node == null && stack.Count > 0)
                {
                    node = stack.Pop();
                    node.Write();
                    node = node.Right;

                }
            }
        }

        public void InOrder1()
        {

            Stack<Node<T>> stack = new Stack<Node<T>>();
            Node<T> node = Root;
            while (node != null || stack.Count > 0)
            {
                if (node != null)
                {
                    stack.Push(node);
                    node = node.Left;
                }
                else
                {
                    node = stack.Pop();
                    node.Write();
                    node = node.Right;
                }
            }
        }
        public void BackOrder()
        {

            Stack<Node<T>> stack = new Stack<Node<T>>();
            Node<T> node = null;
            Node<T> pre = null;
            stack.Push(Root);

            while (stack.Count > 0)
            {
                node = stack.Peek();
                if((node.Left==null&&node.Right==null)||(pre!=null&&(pre==node.Left||pre==node.Right)))
                {
                    node.Write();
                    pre = node;
                    stack.Pop();
                }
                else
                {
                    if(node.Right!=null)
                    {
                        stack.Push(node.Right);
                    }

                    if (node.Left != null)
                    {
                        stack.Push(node.Left);
                    }

                }
            }
        }

        public void BackOrder1()
        {

            Stack<Node<T>> lstack = new Stack<Node<T>>();
            Stack<Node<T>> rstack = new Stack<Node<T>>();
            Node<T> node = root,right=null;


            do
            {
                while(node!=null)
                {
                    right = node.Right;
                    lstack.Push(node);
                    rstack.Push(right);
                    node = node.Left;
                }
                node = lstack.Pop();
                right = rstack.Pop();
                if(right==null)
                {
                    node.Write();
                }
                else
                {
                    lstack.Push(node);
                    rstack.Push(null);
                }
                node = right;

            } while (rstack.Count > 0 || rstack.Count > 0);
        }

    }


    /// <summary>
    /// 二叉树的节点
    /// </summary>
    /// <typeparam name="T"></typeparam>
    class Node<T> : IComparable<T>  where T : IComparable<T>, IPrint
    {
        private T data;

        public T Data
        {
            get { return data; }
            set { data = value; }
        }

        private Node<T> left;
        public Node<T> Left
        {
            get { return left; }
            set { left = value; }
        }

        private Node<T> right;
        public Node<T> Right
        {
            get { return right; }
            set { right = value; }
        }

        public Node (T data)
        {
            this.data = data;
        }

        public virtual int CompareTo(T other)
        {
            return this.CompareTo(other);
        }


        /// <summary>
        /// 先序遍历(根节点-->左孩子-->右孩子)
        /// </summary>
        public virtual void FrontRootOrder()
        {
            Data.Print();
            if(Left!=null)
            {
                Left.FrontRootOrder();
            }
            if(Right!=null)
            {
                Right.FrontRootOrder();
            }
            
        }

        /// <summary>
        /// 中序遍历(左孩子-->根节点-->右孩子)
        /// </summary>
        public virtual void InRootOrder()
        {
            
            if (Left != null)
            {
                Left.InRootOrder();
            }
            Data.Print();
            if (Right != null)
            {
                Right.InRootOrder();
            }
        }

        /// <summary>
        /// 后序遍历(左孩子-->右孩子-->根节点)
        /// </summary>
        public virtual void BackRootOrder()
        {
            if (Left != null)
            {
                Left.BackRootOrder();
            }
            
            if (Right != null)
            {
                Right.BackRootOrder();
            }
            Data.Print();
        }
        public void Write()
        {
            Data.Write();
        }
        public string ToString()
        {
            return Data.ToString();
        }
    }

    /// <summary>
    /// 二叉树节点的数据元素
    /// </summary>
    class DataElement : IComparable<DataElement>, IPrint
    {
        private string data;

        public string Data
        {
            get { return data; }
            set { data = value; }
        }

        public DataElement(string data)
        {
            this.data = data;
        }
        public int CompareTo(DataElement element)
        {
            return this.Data.CompareTo(element.Data);
        }

        public void Print()
        {
            Console.Write(data+",");
        }
        public void Write()
        {
            Console.Write(data+",");
        }
        public string ToString()
        {
            return data;
        }
    }
}

测试的两个二叉树:
在这里插入图片描述

测试代码

/*
 * author:codingriver
 * 20181016 21:46
 */

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

namespace TreeTest
{
    class Program
    {
        static void Main(string[] args)
        {
            int[] array1 = new int[] { 1, 2, 3, '#', '#', 4, '#', '#', 5, 6 };
            TestTree(array1);
            Console.WriteLine("\n\n***********************************************\n\n");
            int[] array2 = new int[] { 1, 2, '#', 3, '#', '#', 4, 5, '#', 6, '#', 7, '#', '#', 8 };
            TestTree(array2);
        }

        static void TestTree(int[] arr)
        {

            Tree<DataElement> tree = CreateTree(arr);
            tree.FrontRootOrder();
            Console.WriteLine("\n============================");
            tree.InRootOrder();
            Console.WriteLine("\n============================");
            tree.BackRootOrder();
            Console.WriteLine("\n============================");
            tree.LevelOrder();
            Console.WriteLine("\n============================");
            Console.WriteLine("\n==========非递归遍历==================");
            Console.WriteLine("\n============前序================");
            tree.FontOrder();
            Console.WriteLine("\n");
            tree.FontOrder1();
            Console.WriteLine("\n============中序================");
            tree.InOrder();
            Console.WriteLine("\n");
            tree.InOrder1();
            Console.WriteLine("\n============后序================");
            tree.BackOrder();
            Console.WriteLine("\n");
            tree.BackOrder1();
        }


        /// <summary>
        /// 创建二叉树
        /// </summary>
        static Tree<DataElement> CreateTree(int[] arr)
        {


            int len = arr.Length;

            Func<string, Node<DataElement>> createNode = (data) =>
            {
                var node = new Node<DataElement>(new DataElement(data));
                return node;
            };

            int index = 0;
            Func<Node<DataElement>> createTree = null;
            createTree = () =>
            {
                Node<DataElement> node = null;
                if (index < len && arr[index] != '#')
                {
                    node = createNode(arr[index].ToString());
                    ++index;
                    node.Left = createTree();
                    ++index;
                    node.Right = createTree();
                }
                return node;
            };

            Tree<DataElement> tree = new Tree<DataElement>();
            tree.Root = createTree();
            return tree;
        }

    }
}

测试结果:

在这里插入图片描述

这篇文章整理的不够细致,后面补充吧

参考文章:
二叉树的递归与非递归实现
C#二叉树的实现

猜你喜欢

转载自blog.csdn.net/codingriver/article/details/83186365