C#代碼創建二叉樹以及遍歷二叉樹


轉自   https://blog.csdn.net/qq_45071375/article/details/103715587

這是我們用代碼創建出來的二叉樹圖例

      A

     /  \

    B   C

   /  \   \

  D   E   F

 

友情提示:
在下面代碼中出現的#字符代表子樹為空,例如D結點下面左右子樹都沒有,就是兩個#號;C結點沒有左子樹就是一個#號,具體看Main函數運行代碼!

 

 

一,字段腳本

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

namespace BinaryDemo
{
    public class TreeNode
    {
        /*
         * 樹的知識點
         * 樹結點 根結點 結點子樹
         * 結點的度  結點關系 結點層次
         * 樹的深度/高度
         */
        //結點下標  結點下標字符串數據 左子樹 右子樹
        private int index;
        private string data;
        private TreeNode leftChild;
        private TreeNode rightChild;
        private TreeNode parent;


        /// <summary>
        /// 有參構造結點下標  結點下標的字符串數據
        /// </summary>
        /// <param name="index"></param>
        /// <param name="data"></param>
        public TreeNode(int index, string data)
        {
            this.index = index;
            this.data = data;
            this.leftChild = null;
            this.rightChild = null;
        }

        public int getIndex()
        {
            return index;
        }
        public void setIndex(int index)
        {
            this.index = index;
        }
        //拿到左右子串的數據
        public String getData()
        {
            return data;
        }
        public void setData(String data)
        {
            this.data = data;
        }
        //拿到左子樹
        public TreeNode getLeftChild()
        {
            return leftChild;
        }
        public void setLeftChild(TreeNode leftChild)
        {
            this.leftChild = leftChild;
        }
        //拿到右子樹
        public TreeNode getRightChild()
        {
            return rightChild;
        }
        public void setRightChild(TreeNode rightChild)
        {
            this.rightChild = rightChild;
        }
        public TreeNode getParent()
        {
            return parent;
        }
        public void setParent(TreeNode parent)
        {
            this.parent = parent;
        }
        //快捷鍵生成的字段get和set
        public int Index { get => index; set => index = value; }
        public string Data { get => data; set => data = value; }
        public TreeNode LeftChild { get => leftChild; set => leftChild = value; }
        public TreeNode RightChild { get => rightChild; set => rightChild = value; }
        public TreeNode Parent { get => parent; set => parent = value; }
    }
}

二,二叉樹具體實現構建遍歷的腳本

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

namespace BinaryDemo
{
    public class BinaryTree
    {
        //根結點
        public TreeNode root = null;
        public static string[] str;
        public static int count;
        /// <summary>
        /// 無參構造設置根結點並賦值數據
        /// </summary>
        public BinaryTree()
        {
            root = new TreeNode(1,"A");
        }
        /// <summary>
        /// 構建二叉樹的方法    B C D E F
        /// 手動的構建一棵二叉樹  很快就可以得出這個二叉樹的結構
        /// </summary>
        public void CreateBinaryTree()
        {
            TreeNode nodeb = new TreeNode(2,"B");
            TreeNode nodec = new TreeNode(3, "C");
            TreeNode noded = new TreeNode(4, "D");
            TreeNode nodee = new TreeNode(5, "E");
            TreeNode nodef = new TreeNode(6, "F");
            root.LeftChild = nodeb;
            root.RightChild = nodec;
            nodeb.LeftChild = noded;
            nodeb.RightChild = nodee;
            nodec.RightChild = nodef;
        }
        /// <summary>
        /// 先序遍歷 --迭代
        /// 若二叉樹為空樹直接返回,先序遍歷的特點根左右
        /// </summary>
        public void PreOrder(TreeNode node)
        {
            if (node == null)
            {
                return;
            }
            else
            {
                //node.getData()我們可以獲取到二叉樹的根結點的數據
                Console.WriteLine("先序遍歷" + "\t迭代" + node.getData());
                //得到左子樹的數據
                PreOrder(node.LeftChild);
                //得到右子樹的數據
                PreOrder(node.RightChild);
            }
        }
        /// <summary>
        /// 中序遍歷--迭代
        /// 若二叉樹為空樹直接返回,中序遍歷的特點左根右
        /// </summary>
        /// <param name="node"></param>
        public void MidOrder(TreeNode node)
        {
            if (node == null)
            {
                return;
            }
            else
            {
                MidOrder(node.LeftChild);
                Console.WriteLine("中序遍歷" + "\t迭代" + node.getData());
                MidOrder(node.RightChild);
            }
        }
        /// <summary>
        /// 后序遍歷--迭代
        /// 若二叉樹為空樹直接返回,中序遍歷的特點左右根
        /// </summary>
        /// <param name="node"></param>
        public void LastOrder(TreeNode node)
        {
            if (node == null)
            {
                return;
            }
            else
            {
                LastOrder(node.LeftChild);
                LastOrder(node.RightChild);
                Console.WriteLine("后序遍歷" + "\t迭代" + node.getData());
            }
        }
        
        //-----------------------------------分界線------------------------------------------
        
        /*
         迭代與普通循環的區別是:迭代時,循環代碼中參與運算的變量同時是保存結果的變量,
         當前保存的結果作為下一次循環計算的初始值。
         
         遞歸與普通循環的區別是:循環是有去無回,而遞歸則是有去有回(因為存在終止條件)。
         */
        /// <summary>
        /// 根據先序序列構建二叉樹
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public TreeNode CreateBinaryTree(List<String> data)
        {
            return CreateBinaryTree(data.Count, data);
        }
        /// <summary>
        /// 根據先序遞歸創建二叉樹 
        /// "A","B","D","#","#","E","#","#","C","#","F","#","#"
        /// 1、首先判斷集合的長度是否為0,為空樹或者結點都已經賦值成功
        /// 2、把存儲每個結點的集合以及長度傳參進來  index為結點下標
        /// 3、先序遍歷根左右首先確定根結點也就是集合的第0項,結點下標為0結點數據為A,從集合中刪除結點數據
        /// A,現在集合中有12數量
        ///
        /// 4、然后進到獲取左子樹結點里面,結點B、D一樣的執行原理,
        /// 5、注意#的使用   #號代表結點沒有左子樹或者右子樹 一個#代表沒有左子樹,但是有右子樹 兩個#左右子
        /// 樹都沒有
        ///
        /// 6、注意里面的順序  根結點 左子樹  如果出現#號  根據個數判斷  一層一層的遍歷
        /// </summary>
        /// <param name="count"></param>
        /// <param name="data"></param>
        /// <returns></returns>
        private TreeNode CreateBinaryTree(int count, List<string> data)
        {
            if (data.Count == 0)
            {
                return null;
            }
            string d = data[0];
            
            TreeNode node = null;
            int index = count - data.Count;
            if (d.Equals("#"))
            {
                node = null;
                data.RemoveAt(0);//刪除#
                return node;//退出
            }
            
            node = new TreeNode(index,d);//創建新的結點
            if (index == 0)
            {
                root = node;
            }
            data.RemoveAt(0);
            node.LeftChild = CreateBinaryTree(count, data);
            node.RightChild = CreateBinaryTree(count, data);
            return node;
        }

        /// <summary>
        /// 求二叉樹的高度
        /// </summary>
        /// <returns></returns>
        public int GetHeight()
        {
            return GetHeight(root);
        }

        private int GetHeight(TreeNode node)
        {
            //根結點為空  高度為0
            if (node == null)
            {
                return 0;
            }
            else
            {
                Console.WriteLine(node.getData());
                //求出左子樹和右子樹的高度  
                int i = GetHeight(node.LeftChild);
                int j = GetHeight(node.RightChild);
                //左右子樹的高度就是樹的深度   三目運算符判斷哪棵子樹的高度高  樹的高度就是返回值
                return (i < j) ? j + 1 : i + 1;
            }
        }


        /// <summary>
        /// 獲取二叉樹的結點數
        /// </summary>
        /// <returns></returns>
        public int GetSize()
        {
            return GetSize(root);
        }

        private int GetSize(TreeNode node)
        {
            //沒有根結點即為空樹  所以也就不存在結點
            if (node == null)
            {
                return 0;
            }
            else
            {
                //不是空樹的情況下  拿到所有的左子樹的結點和右子樹的結點  最后加上根結點
                return 1 + GetSize(node.LeftChild) + GetSize(node.RightChild);
            }
        }
        

        /// <summary>
        /// 前序遍歷-------非迭代
        /// 棧里面的操作A進棧-->B進棧-->D進棧-->D出棧-->B出棧-->E進棧-->E出棧-->A出棧-->C進棧-->C出棧
        ///-->F進棧-->F出棧
        /// </summary>
        /// <param name="root"></param>
        public void TheFirstOrder(TreeNode root)
        {
            Stack<TreeNode> stack = new Stack<TreeNode>();
            TreeNode node = root;
            //結點數不為空或者棧的數量大於0
            while (node != null||stack.Count>0)
            {
                if (node != null)
                {
                    Console.WriteLine("前序遍歷"+"非迭代進棧"+node.getData());
                    stack.Push(node);//壓棧訪問
                    node = node.LeftChild;
                }
                else
                {
                    //彈棧 
                    node = stack.Pop();
                    node=node.RightChild;
                }
            }
        }
        /// <summary>
        /// 中序遍歷-------非迭代
        /// </summary>
        /// <param name="root"></param>
        public void TheMidleOrder(TreeNode root)
        {
            Stack<TreeNode> stack = new Stack<TreeNode>();
            TreeNode node = root;
            while (node != null || stack.Count > 0)
            {
                if (node != null)
                {
                    stack.Push(node);//壓棧
                    node = node.LeftChild;
                }
                else
                {
                    node = stack.Pop();//彈棧訪問
                    Console.WriteLine("中序遍歷" + "非迭代出棧" + node.getData());
                    node = node.RightChild;
                }
            }
        }
        /// <summary>
        /// 后序遍歷-------非迭代
        /// </summary>
        /// <param name="root"></param>
        public void TheLastOrder(TreeNode root)
        {
            Stack<TreeNode> stack = new Stack<TreeNode>();
            Stack<TreeNode> output = new Stack<TreeNode>();//新建一個中間棧來存儲后序遍歷的結果
            TreeNode node = root;
            //先序遍歷根左右  后序遍歷左右根  首先確定根結點  右子樹 左子樹  反過來就行  
            while (node != null || stack.Count > 0)
            {
                if (node != null)
                {
                    output.Push(node);
                    stack.Push(node);
                    node = node.RightChild;
                }
                else
                {
                    //彈棧
                    node = stack.Pop();
                    node = node.LeftChild;
                }
            }
            while (output.Count > 0)
            {
                Console.WriteLine("后序遍歷"+"非迭代"+output.Pop().getData());
            }
        }
    }
}

三,Main方法調試

using System;
using System.Collections.Generic;

namespace BinaryDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            //方法一
            /*
            BinaryTree binarytree = new BinaryTree();
            //在代碼中手動的創建了二叉樹
            binarytree.CreateBinaryTree();
            //先序遍歷
            binarytree.PreOrder(binarytree.root);
            Console.WriteLine();
            //中序遍歷
            binarytree.MidOrder(binarytree.root);
            Console.WriteLine();
            //后序遍歷
            binarytree.LastOrder(binarytree.root);
            */
            
            //方法二
            
            //用集合存儲所有的結點
            List<String> data = new List<string>();
            //存儲先序遍歷每一個結點的數組
            String[] dataArray = new string[] {"A","B","D","#","#","E","#","#","C","#","F","#","#"};
            //遍歷存儲結點的數組存儲到集合里面
            foreach (string item in dataArray)
            {
                data.Add(item);
            }
            BinaryTree binary = new BinaryTree();
            binary.CreateBinaryTree(data);//創建二叉樹

            int height = binary.GetHeight();//求二叉樹的高度
            Console.WriteLine("二叉樹的高度是"+height);

            int size = binary.GetSize();//過去所以的結點數
            Console.WriteLine("二叉樹的結點數是"+size);
            binary.TheFirstOrder(binary.root);
            Console.WriteLine();
            binary.TheMidleOrder(binary.root);
            Console.WriteLine();
            binary.TheLastOrder(binary.root);
            
            Console.ReadKey();
        }
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM