二叉樹的一些基礎演算法

來源:互聯網
上載者:User

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

namespace BitTree
{
    //TODO:列印二叉樹

    class Constant
    {
        public static readonly string Space = " ";
    }

    class Program
    {
        static void Main(string[] args)
        {
           //" "表示葉子結點

            string preorder = "ABC  DE G  F  ";
            //string preorder = "ABDH  I  EJ  K  CFL   G  ";

            Console.WriteLine("樹結點:{0}", preorder);
            BitTree bt = new BitTree(preorder);
            Node root = bt.CreateBitTreePreOrder();

            int width = bt.GetTreeWidth(root);

            Console.WriteLine("樹寬:{0}", width);            

            //樹高
            int depth = bt.GetTreeDepth(root);
            Console.WriteLine("樹高遞迴演算法:{0}", depth);

            depth = bt.GetTreeDepthNoneRecursion(root);
            Console.WriteLine("樹高非遞迴演算法:{0}", depth);

            //先序
            Console.WriteLine("先序遞迴遍曆:");
            bt.PreTraverse(root);
            Console.WriteLine();
            Console.WriteLine("先序非遞迴遍曆:");
            bt.PreTraverseNoneRecursion(root);
            Console.WriteLine();

            //中序
            Console.WriteLine("中序遞迴遍曆:");
            bt.MidTraverse(root);
            Console.WriteLine();
            Console.WriteLine("中序非遞迴遍曆:");
            bt.MidTraverseNoneRecursion(root);
            Console.WriteLine();

            //後序
            Console.WriteLine("後序遞迴遍曆:");
            bt.PostTraverse(root);
            Console.WriteLine();

            Console.WriteLine("後序非遞迴遍曆:");
            bt.PostTraverseNoneRecursion(root);
            Console.WriteLine();

            //層次遍曆
            Console.WriteLine("層次遍曆:");
            bt.TopToBottomReserver(root);
            Console.ReadLine();
        }
    }

    internal class Node
    {
        internal Node Left { get; set; }
        internal Node Right { get; set; }
        internal string Value { get; set; }
    }

    class BitTree
    {
        string inputSequence;

        public BitTree(string input)
        {
            inputSequence = input;
        }

        #region 先序演算法
        //先序建立二叉樹
        public Node CreateBitTreePreOrder()
        {
            return CreateBitTreePreOrder(null);
        }

        private Node CreateBitTreePreOrder(Node node)
        {
            if (string.IsNullOrEmpty(inputSequence))
            {
                return null;
            }

            string value = inputSequence.Substring(0, 1);
            inputSequence = inputSequence.Substring(1);

            if (string.IsNullOrEmpty(value) || value == Constant.Space)
            {
                return null;
            }

            node = new Node();
            node.Value = value;
            node.Left = CreateBitTreePreOrder(node.Left);
            node.Right = CreateBitTreePreOrder(node.Right);

            return node;
        }

        //先序遍曆二叉樹,遞迴
        public void PreTraverse(Node node)
        {
            if (node != null)
            {
                Console.Write(node.Value);
                PreTraverse(node.Left);
                PreTraverse(node.Right);
            }
        }

        //先序遍曆二叉樹,非遞迴
        public void PreTraverseNoneRecursion(Node node)
        {
            Stack<Node> stack = new Stack<Node>();

            while (node != null || stack.Count > 0)//while用的很牛
            {
                if (node != null)//壓棧同時訪問
                {
                    Console.Write(node.Value);
                    stack.Push(node);
                    node = node.Left;
                }
                else//處理右邊
                {
                    node = stack.Pop();
                    node = node.Right;
                }
            }
        }

        #endregion

        #region 中序遍曆演算法

        //中序不能唯一確定一顆二叉樹

        //中序遍曆二叉樹,遞迴
        public void MidTraverse(Node node)
        {
            if (node != null)
            {
                MidTraverse(node.Left);
                Console.Write(node.Value);
                MidTraverse(node.Right);
            }
        }

        //中序遍曆二叉樹,非遞迴
        public void MidTraverseNoneRecursion(Node node)
        {
            Stack<Node> stack = new Stack<Node>();

            while (node != null || stack.Count > 0)//while用的很牛
            {
                if (node != null)//壓棧
                {
                    stack.Push(node);
                    node = node.Left;
                }
                else//彈出後訪問
                {
                    node = stack.Pop();
                    Console.Write(node.Value);
                    node = node.Right;
                }
            }
        }

        #endregion

        #region 後序遍曆演算法

        //後序遍曆二叉樹,遞迴
        public void PostTraverse(Node node)
        {
            if (node != null)
            {
                PostTraverse(node.Left);
                PostTraverse(node.Right);
                Console.Write(node.Value);
            }
        }

        //後序遍曆二叉樹,非遞迴
        public void PostTraverseNoneRecursion(Node node)
        {
            Stack<Node> stack = new Stack<Node>();

            Node lastvisit = node;//最後訪問的結點

            while (node != null || stack.Count > 0)
            {
                if (node != null)
                {
                    stack.Push(node);
                    node = node.Left;
                }
                else
                {
                    Node p = stack.Peek();//取而不出

                    //    || (p.Right == lastvisit))//若右邊為空白,或已經訪問過,則返回到父結點
                    if(p.Right == null || p.Right == lastvisit)
                    {
                        stack.Pop();
                        Console.Write(p.Value);
                        lastvisit = p;
                    }
                    else//非葉結點,右邊未訪問過,訪問右邊
                    {
                        node = p.Right;
                    }
                }
            }
        }

        #endregion

        #region 層次遍曆

        public void TopToBottomReserver(Node node)
        {
            Queue<Node> queue = new Queue<Node>();

            queue.Enqueue(node);
            while (queue.Count > 0)
            {
                node = queue.Dequeue();

                if (node != null)
                {
                    Console.Write(node.Value);

                    queue.Enqueue(node.Left);
                    queue.Enqueue(node.Right);
                }
            }
        }

        #endregion

        #region 樹高
        public int GetTreeDepth(Node node)
        {
            if (node == null)
            {
                return 0;
            }
            else if (node.Left == null && node.Right == null)
            {
                return 1;
            }
            else
            {
                int ldepth = GetTreeDepth(node.Left);
                int rdepth = GetTreeDepth(node.Right);
                return ldepth > rdepth ? 1 + ldepth : 1 + rdepth;
            }
        }

        //方法和遍曆一樣,用兩個int作標記
        public int GetTreeDepthNoneRecursion(Node root)
        {
            int depth = 0;

            Stack<Node> stack = new Stack<Node>();

            Node lastvisit = root;//最後訪問的結點

            while (root != null || stack.Count > 0)
            {
                if (root != null)
                {
                    stack.Push(root);

                    depth = stack.Count > depth ? stack.Count : depth;
                    root = root.Left;
                }
                else
                {
                    Node p = stack.Peek();//取而不出

                    if (p.Right == null || p.Right == lastvisit)
                    {
                        stack.Pop();
                        lastvisit = p;
                    }
                    else//非葉結點,右邊未訪問過,訪問右邊
                    {
                        root = p.Right;
                    }
                }
            }

            return depth;
        }
        #endregion

        public int GetTreeWidth(Node root)
        {
            if (root == null)
            {
                return 0;
            }
            else if (root.Left == null && root.Right == null)
            {
                return 1;
            }
            else
            {
                int lwidth = GetTreeWidth(root.Left);
                int rwidth = GetTreeWidth(root.Right);

                return 1 + lwidth - rwidth;
            }
        }

        //返回結點總數
        public int GetNodeCount(Node root)
        {
            if (root == null)
            {
                return 0;
            }
            else if (root.Left == null && root.Right == null)
            {
                return 1;
            }
            else
            {
                int lwidth = GetNodeCount(root.Left);
                int rwidth = GetNodeCount(root.Right);

                return 1 + lwidth + rwidth;
            }
        }

        //得到指定層上所有結點
        private List<Node> GetNodeListInDepth(Node root, int depthNum)
        {
            int treeheight = GetTreeDepth(root);

            if (root == null || depthNum > treeheight)
            {
                return new List<Node>();
            }

            List<Node> sumNode = new List<Node>();

            if(depthNum == 1)
            {
                sumNode.Add(root);
                return sumNode;
            }

            Node node = root;

            List<Node> lchilrenlist = new List<Node>();
            lchilrenlist = GetNodeListInDepth(node.Left, depthNum - 1);

            List<Node> rchilrenlist = new List<Node>();
            rchilrenlist = GetNodeListInDepth(node.Right, depthNum - 1);

            sumNode.AddRange(lchilrenlist);
            sumNode.AddRange(rchilrenlist);

            return sumNode;
        }

    }
}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.