C#內功修鍊(演算法)——樹(二 )__演算法

來源:互聯網
上載者:User

樹結構

樹是一種重要的非線性資料結構,直觀地看,它是資料元素(在樹中稱為結點)按分支關係組織起來的結構,很象自然界中的樹那樣。

樹是一種重要的非線性資料結構,直觀地看,它是資料元素(在樹中稱為結點)按分支關係組織起來的結構,很象自然界中的樹那樣。樹結構在客觀世界中廣泛存在,如人類社會的族譜和各種社會組織機構都可用樹形象表示。樹在電腦領域中也得到廣泛應用,如在編譯來源程式如下時,可用樹表示源來源程式如下的文法結構。又如在資料庫系統中,樹型結構也是資訊的重要組織形式之一。一切具有層次關係的問題都可用樹來描述。

樹的關係複雜使用鏈式儲存

1,雙親標記法


2,孩子標記法



3,孩子兄弟標記法




二叉樹:

一般的樹來說是一對多的關係,使用順序結構儲存起來比較困難,但是二叉樹是一種特殊的樹,每個結點最多有兩個子節點,並且子節點有左右之分,並且兄弟,父親,孩子可以很方便的通過編號得到,所以我們使用順序儲存結構使用二叉樹的儲存。

二叉樹每個結點最多有兩個孩子,所以為它設計一個資料域和兩個指標域,我們稱這樣的鏈表為二叉鏈表。




二叉樹特性:

1,在二叉樹的第i層上最多有 2i-1個結點(i>=1)

2,深度為k的二叉樹至多有2k-1個結點

  20+21+22+23+24+25+26+27+.....+2k-1+-1

  =1+20+21+22+23+24+25+26+27+.....+2k-1-1

  =21+21+22+23+24+25+26+27+.....+2k-1-1

  =22+22+23+24+25+26+27+.....+2k-1-1

  =23+23+24+25+26+27+.....+2k-1-1

  =2k-1+2k-1-1

  =2k-1

3,對於一個完全二叉樹,假設它有n個結點,對結點進行從1開始編號,對任一結點i滿足下面

  a,它的雙親是結點i/2  (除了i=1的情況)

  b,左孩子是2i  右孩子是2i+1

  c,如果2i>n 說明無左孩子   2i+1>n說明無右孩子


二叉樹儲存:

順序儲存:

private char[] _data = new[] {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J'};    private void UseTree()    {        BiTree<char> biTree = new BiTree<char>(_data.Length);        for (int i = 0; i < _data.Length; i++)        {            biTree.Add(_data[i]);        }    }    public class BiTree<T>    {        public T[] Data;        public int Count;        public BiTree(int capactiy)        {            Data = new T[capactiy];            Count = 0;        }        public bool Add(T item)        {            if (Count >= Data.Length) return false;            Data[Count] = item;            Count++;            return true;        }    }

鏈式儲存:

二叉樹遍曆:

1,前序走訪

    先輸出當前結點的資料,再依次遍曆輸出左結點和右結點

        /// <summary>        /// 前序走訪        /// </summary>        public void FirstTraversal(int index)        {            if (index >= Data.Length) return;            //遍曆節點編號            int munber = index + 1;            if (Data[index].Equals(-1)) return;            Debug.Log(Data[index]);            int leftNumber = munber*2;            int rightNumber = munber*2 + 1;            FirstTraversal(leftNumber - 1);            FirstTraversal(rightNumber - 1);        }

2,中序遍曆

    先遍曆輸出左結點,再輸出當前結點的資料,再遍曆輸出右結點

    GDH B A E I C F

        /// <summary>        /// 中序遍曆        /// </summary>        public void MiddleTraversal(int index)        {            if (index >= Data.Length) return;            //遍曆節點編號            int munber = index + 1;            if (Data[index].Equals(-1)) return;            int leftNumber = munber * 2;            int rightNumber = munber * 2 + 1;            MiddleTraversal(leftNumber - 1);            Debug.Log(Data[index]);            MiddleTraversal(rightNumber - 1);        }

3,後序遍曆

    先遍曆輸出左結點,再遍曆輸出右結點,最後輸出當前結點的資料

 G H D B I E F C A

        /// <summary>        /// 後序遍曆        /// </summary>        public void LastTraversal(int index)        {            if (index >= Data.Length) return;            //遍曆節點編號            int munber = index + 1;            if (Data[index].Equals(-1)) return;            int leftNumber = munber * 2;            int rightNumber = munber * 2 + 1;            LastTraversal(leftNumber - 1);            LastTraversal(rightNumber - 1);            Debug.Log(Data[index]);        }

4,層序遍曆

    從樹的第一層開始,從上到下逐層遍曆,在同一層中,從左至右對結點 逐個訪問輸出

        /// <summary>        /// 層遍曆        /// </summary>        public void LayerTraversal()        {            for (int i = 0; i < Count; i++)            {                Debug.Log(Data[i]);            }        }

二叉排序樹:

二叉排序樹,又稱為二叉尋找樹。它或者是一棵空樹,或者是具有下列性質的二叉樹。

      若它的左子樹不為空白,則左子樹上所有的結點的值均小於根結構的值;

      若它的右子樹不為空白,則右字數上所有結點的值均大於它的根結點的值;

      它的左右子樹也分別為二叉排序樹。

    /// <summary>    /// 樹類    /// </summary>    public class BSTree    {        private BSNode _rootNode;        /// <summary>        /// 增加        /// </summary>        /// <param name="item"></param>        public void Add(int item)        {            BSNode newNode = new BSNode(item);            if (_rootNode == null)            {                _rootNode = newNode;            }            else            {                BSNode temp = _rootNode;                while (true)                {                    if (item >= temp.Data) //放右面                    {                        if (temp.RightNode == null) //右節點空                        {                            temp.RightNode = newNode;                            temp.ParentNode = temp;                            break;                        }                        temp = temp.RightNode;                    }                    else   //放左面                    {                        if (temp.LeftNode == null)                        {                            temp.LeftNode = newNode;                            temp.ParentNode = temp;                            break;                        }                        temp = temp.LeftNode;                    }                }            }        }        /// <summary>        /// 尋找        /// </summary>        public bool Find(int item, BSNode node)        {            if (node == null) return false;            if (node.Data == item) return true;            if (item > node.Data) return Find(item, node.RightNode);            if (item < node.Data) return Find(item, node.LeftNode);            return false;        }        /// <summary>        /// 刪除        /// </summary>        public bool Delete(int item)        {            BSNode temp = _rootNode;            while (true)            {                if (temp == null) return false;                if (temp.Data == item)                {                    Delete(temp);                    return true;                }                temp = temp.Data > item ? temp.LeftNode : temp.RightNode;            }        }        private void Delete(BSNode node)        {            if (node.ParentNode == null)            {                _rootNode = null;                return;            }            //判斷是否是分葉節點            if (node.LeftNode == null && node.RightNode == null)            {                if (node.ParentNode.LeftNode == node)                    node.ParentNode.LeftNode = null;                else                    node.ParentNode.RightNode = null;                return;;            }            //只有左子樹或只有右子樹            if (node.LeftNode == null && node.RightNode != null)            {                node.Data = node.RightNode.Data;                node.RightNode = null;                return;            }            if (node.LeftNode != null && node.RightNode == null)            {                node.Data = node.LeftNode.Data;                node.LeftNode = null;                return;            }            //左右子樹都有            BSNode temp = node.RightNode;            while (true)            {                if (temp.LeftNode != null)                {                    temp = temp.LeftNode;                }                else                {                    break;                }            }            node.Data = temp.Data;            Delete(temp);        }    }    /// <summary>    /// 節點類    /// </summary>    public class BSNode    {        public int Data { get; set; }        public BSNode LeftNode { get; set; }        public BSNode RightNode { get; set; }        public BSNode ParentNode { get; set; }        public BSNode(int item)        {            Data = item;            LeftNode = null;            RightNode = null;            ParentNode = null;        }    }

聯繫我們

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