Java數據結構——樹的三種存儲結構


(轉自http://blog.csdn.net/x1247600186/article/details/24670775)

說到存儲結構,我們就會想到常用的兩種存儲方式:順序存儲和鏈式存儲兩種。

先來看看順序存儲,用一段地址連續的存儲單元依次存儲線性表中數據元素,這對於線性表來說是很自然的,但是對於樹這種一對多的結構而言是否適合呢?

樹中某個結點的孩子可以有多個,這就意味着,無論用哪種順序將樹中所有的結點存儲到數組中,結點的存儲位置都無法直接反映邏輯關系,試想一下,數據元素挨個存儲,那么誰是誰的雙親,誰是誰的孩子呢?所以簡單的順序存儲是不能滿足樹的實現要求的。

不過可以充分利用順序存儲和鏈式存儲結構的特點,完全可以實現對樹的存儲結構的表示。

下面介紹三種不同的樹的表示法:雙親表示法,、孩子表示法,、孩子兄弟表示法。

1、雙親表示法:

     我們假設以一組連續空間存儲樹的結點,同時在每個結點中,附設一個指示器指向其雙親結點到鏈表中的位置。也就是說每個結點除了知道自己之外還需要知道它的雙親在哪里。

它的結構特點是如圖所示:            

                               

以下是我們的雙親表示法的結構定義代碼:

     /*樹的雙親表示法結點結構定義  */  
    #define MAXSIZE 100  
    typedef int ElemType;       //樹結點的數據類型,暫定為整形   
    typedef struct PTNode       //結點結構  
    {  
        ElemType data;          //結點數據  
        int parent;             //雙親位置  
    }PTNode;  
      
    typedef struct  
    {  
        PTNode nodes[MAXSIZE];  //結點數組  
        int r,n;                //根的位置和結點數  
    }PTree;  

 

2、孩子表示法

換一種不同的考慮方法。由於每個結點可能有多棵子樹,可以考慮使用多重鏈表,即每個結點有多個指針域,其中每個指針指向一棵子樹的根結點,我們把這種方法叫做多重鏈表表示法。不過樹的每個結點的度,也就是它的孩子個數是不同的。所以可以設計兩種方案來解決。

方案一:

一種是指針域的個數就等於樹的度(樹的度是樹的各個結點度的最大值)

其結構如圖所示:

                                   

不過這種結構由於每個結點的孩子數目不同,當差異較大時,很多結點的指針域就都為空,顯然是浪費空間的,不過若樹的各結點度相差很小時,那就意味着開辟的空間都被利用了,這時這種缺點反而變成了優點。


方案二:

第二種方案是每個結點指針域的個數等於該結點的度,我們專門取一個位置來存儲結點指針域的個數。

其結構如圖所示:

                 

 

這種方法克服了浪費空間的缺點,對空間的利用率是很高了,但是由於各個結點的鏈表是不相同的結構,加上要維護結點的度的數值,在運算上就會帶來時間上的損耗。

能否有更好的方法呢,既可以減少空指針的浪費,又能是結點結構相同。

說到這大家肯定就知道是有的麥,那就是孩子表示法。

具體辦法是,把每個結點的孩子排列起來,以單鏈表做存儲結構,則n個結點有n個孩子鏈表,如果是葉子結點則此單鏈表為空。然后n個頭指針有組成一個線性表,采用順序存儲結構,存放進入一個一維數組中

為此,設計兩種結點結構,

一個是孩子鏈表的孩子結點,如下所示:

 

其中child是數據域,用來存儲某個結點在表頭數組中的下標。next是指針域,用來存儲指向某結點的下一個孩子結點的指針。

另一個是表頭結點,如下所示:

 

 

其中data是數據域,存儲某結點的數據信息。firstchild是頭指針域,存儲該結點的孩子鏈表的頭指針。

以下是孩子表示法的結構定義代碼:

    /*樹的孩子表示法結點結構定義  */  
    #define MAXSIZE 100  
    typedef int ElemType;       //樹結點的數據類型,暫定為整形   
    typedef struct CTNode       //孩子結點  
    {  
        int child;  
        struct CTNode *next;  
    }*ChildPtr;  
      
    typedef struct              //表頭結構  
    {  
        ElemType data;  
        ChildPtr firstchild;  
    }CTBox;  
    typedef struct              //樹結構  
    {  
        CTBox nodes[MAXSIZE];   //結點數組  
        int r,n;                //根結點的位置和結點數  
    }CTree;  

 

3、孩子兄弟表示法

我們發現,任意一顆樹,它的結點的第一個孩子如果存在就是的,它的右兄弟如果存在也是唯一的。因此,我們設置兩個指針,分別指向該結點的第一個孩子和此結點的右兄弟。

其結點結構如圖所示:

以下是孩子兄弟表示法的結構定義代碼:

        /*樹的孩子兄弟表示法結構定義 */  
        typedef struct CSNode  
        {  
            ElemType  data;  
            struct CSNode  *firstchild, *rightsib;  
        }CSNode, *CSTree;

 


免責聲明!

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



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