C#實現二叉樹(三元素式)及二叉樹遍曆的四種方法

來源:互聯網
上載者:User
 

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

namespace binaryTree
{
    class Program
    {
        static void Main(string[] args)
        {

              //使用者操作
        }
    }

 

    //定義: 二叉樹的儲存結構類
    public class Node<T>
    {
        private T data;  //資料域
        private Node<T> lChild;  //左孩子
        private Node<T> rChild;  //右孩子

        //構造器
        public Node(T val, Node<T> lp, Node<T> rp)
        {
            data = val;
            lChild = lp;
            rChild = rp;
        }

        //構造器
        public Node(Node<T> lp, Node<T> rp)
        {
            data = default(T);
            lChild = lp;
            rChild = rp;
        }

        //構造器
        public Node(T val)
        {
            data = val;
            lChild = null;
            rChild = null;
        }

        //構造器
        public Node(T val)
        {
            data = default(T);
            lChild = null;
            rChild = null;
        }

        //資料屬性
        public T Data
        {
            get
            {
                return data;
            }
            set
            {
                data = value;
            }
        }

        //左孩子屬性
        public Node<T> LChild
        {
            get
            {
                return lChild;
            }
            set
            {
                lChild = value;
            }
        }

        //右孩子屬性
        public Node<T> RChild
        {
            get
            {
                return rChild;
            }
            set
            {
                rChild = value;
            }
        }
    }

    //不帶頭結點的二叉樹的二叉鏈表的類 BiTree<T>
    public class BiTree<T>
    {
        private Node<T> head;  //頭引用

        //構造器
        public BiTree()
        {
            head = null;
        }

        //構造器
        public BiTree(T val)
        {
            Node<T> p = new Node<T>(val);
            head = p;
        }

        //構造器
        public BiTree(T val, Node<T> lp, Node<T> rp)
        {
            Node<T> p = new Node<T>(val, lp, rp);
            head = p;
        }

        //頭引用屬性
        public Node<T> Head
        {
            get
            {
                return head;
            }
            set
            {
                head = value;
            }
        }

        //判斷是否是空二叉樹
        public bool IsEmpty()
        {
            if (head == null)
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        //擷取根結點
        public Node<T> Root()
        {
            return head;
        }

        //擷取結點的左孩子結點
        public Node<T> GetLChild(Node<T> p)
        {
            return p.LChild;
        }

        //擷取結點的右孩子結點
        public Node<T> GetRChild(Node<T> p)
        {
            return p.RChild;
        }

        //將結點p的左子樹插入值為 val的新結點.
        //原來的左子樹成為新結點的左子樹.
        public void InsertL(T val, Node<T> p)
        {
            Node<T> tmp = new Node<T>(val);
            tmp.LChild = p.LChild;  //原來的左子樹成為新結點的左子樹.
            p.LChild = tmp;  //p的左子孩子為新結點.
        }

        //將結點p的右子樹插入值為 val的新結點,
        //原來的右子樹成為新結點的右子樹.
        public void InsertR(T val, Node<T> p)
        {
            Node<T> tmp = new Node<T>(val);
            tmp.RChild = p.RChild; //原來的右子樹成為新結點的右子樹
            p.RChild = tmp;  //p的右孩子為新結點
        }

        //若 p 非空, 刪除 p 的左子樹
        public Node<T> DeleteL(Node<T> p)
        {
            if(( p==null || (p.LChild==null))
            {
                return null;
            }

            Node<T> tmp = p.LChild;
            p.LChild=null;

            return tmp;
        }

        //若 p 非空, 刪除 p 的右子樹
        public Node<T> DeleteR(Node<T> p)
        {
            if ((p == null) || (p.RChild == null))
            {
                return null;
            }

            Node<T> tmp = p.RChild;
            p.RChild = null;

            return tmp;
        }

        //判斷是否是葉子結點
        public bool IsLeaf(Node<T> p)
        {
            if ((p != null) && (p.LChild == null) && (p.RChild == null))
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        //樹的遍曆: 由於樹的定義是遞迴的, 所以遍曆演算法也彩遞迴實現
        //原始順序為: A B C D E F G H I J (原則是 從小到下, 從左至右)
        //1.先序遍曆(DLR), 思想是: 首先訪問根結點, 然後先序遍曆其左子樹, 最後先遍曆其右子樹.
        //結果是: A B D H I E J C F G
        public void PreOrder(Node<T> root)
        {
            //根結點為空白
            if (root == null)
            {
                return;
            }

            //第一步: 處理根結點
            Console.WriteLine("{0}", root.Data);

            //第二步: 遍曆左子樹
            PreOrder(root.LChild);

            //第三步: 遍曆右子樹
            PreOrder(root.RChild);
        }

        //中序遍曆(LDR), 思想是: 首先中序遍曆結點的左子樹, 然後訪問根結點, 最後中序遍曆其右子樹
        //結果為: H DI B E J E A F C G
        public void InOrder(Node<T> root)
        {
            //根結點為空白
            if (root == null)
            {
                return;
            }

            //中序遍曆左子樹
            InOrder(root.LChild);

            //處理根結點,注: 這時的根結點指每一個可以作為父結點的結點.
            Console.WriteLine("{0}", root.Data);

            //中序遍曆右子樹.
            InOrder(root.RChild);
        }

        //後序遍曆(LRD): 基本思想是: 首先遍曆根結點的左子樹, 然後後後序遍曆根結點的右子樹, 最後訪問根結點
        //結果為:  H I D J E B F G C A
        public void PostOrder(Node<T> root)
        {
            //根結點為空白
            if (root == null)
            {
                return;
            }

            //後序遍曆左子樹
            PostOrder(root.LChild);

            //後序遍曆右子樹
            PostOrder(root.RChild);

            //處理根結點
            Console.WriteLine("{0}", root.Data);

        }

        //(4).層序遍曆(Level Order)
        //思想: 由於層次遍曆結點的順序是 先遇到的結點先訪問, 與隊列操作的順序相同.
        //所以, 在進行層次遍曆時, 設定一個隊列, 將根結點引用入隊, 當隊列非空時, 迴圈執行以下三步:
        //(1).從隊列中取出一個結點引用, 並訪問該結點.
        //(2).若該結點的左子樹非空, 將該結點的左子樹引用入隊;
        //(3).若該結點的右子樹非空, 將該結點的右子樹引用入隊;
        public void LevelOrder(Node<T> root)
        {
            //根結點為空白
            if (root == null)
            {
                return;
            }

            //設定一個隊列儲存層序遍曆的結點
            //...此處需要引用到隊列的定義類與操作類, 暫略.
        }
    }
           
}

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.