數據結構與算法 —— 樹(相關知識回顧)

一. 概述

樹的存儲結構應用範圍極爲廣泛,我所瞭解的,如Linux操作系統的目錄結構,DNS域名的存儲,多路複用中的epoll利用的紅黑樹…
那麼,什麼是樹嘞?
在這裏插入圖片描述

這就是一顆樹,下面引出一些概念

  • 空樹

上面的每一個圓圈表示一個結點,用n來表示結點個數,當n等於0是則代表樹是空樹

  • 根節點

當n>0時,樹有且僅有一個根節點,如圖一所示的A結點

  • 結點關係

A是B的雙親結點,B是A的孩子結點,B,C是兄弟,E,F是兄弟

  • 樹的度

也是樹的寬度,即結點的分支樹的個數,如圖一中A結點的度爲3,B結點的度爲2;以組成該樹各節點中最大的度作爲樹的度,圖一樹的度爲3,樹種度爲0的結點稱爲葉子結點或終端結點,度不爲0的結點稱爲分支結點或非終端結點,除終端結點外的分支結點稱爲內部結點

  • 樹的深度

組成該樹各結點的最大層次,圖中的樹深度爲4
在這裏插入圖片描述

  • 森林

若干顆互不相交的樹的集合{T1,T2,T3}

在這裏插入圖片描述

  • 有序樹

如果將樹中結點的各子樹看成從左至右是有次序的,不能互換的,則稱該樹爲有序樹,否則稱爲無序樹

二. 樹的實現

前面學習了順序存儲結構,鏈式存儲結構,樹的實現也需要用到二者,只是,對於樹來說,又有三種表示法,分別是雙親表示法,雙親孩子表示法,孩子兄弟表示法,下面就通過樹的實現來體會這些名字的由來.

2.1 雙親表示法

雙親表示法,即以雙親結點爲索引的個關鍵詞的一種存儲方式,下面來看利用順序存儲的實現:

我們假設以一組連續空間存儲樹的結點,同時在每個結點中,即存儲了本節點的值,還存儲了雙親結點的位置,也就是說結點除了知道“我是誰”,還知道“我的雙親是誰”。

#define MAX_TREE_SIZE 100

typedef int ElemType;

typedef struct PTNode
{
    ElemType data;    //存儲結點的數據
    ElemType parent;  //存儲雙親結點的下標
}PTNode;

typedef struct
{
    PTNode nodes[MAX_TREE_SIZE];  //存儲結點的數組
    int r;  //根的位置
    int n;  //結點個數
}PTree;

來看下面這顆樹:
在這裏插入圖片描述
再來看用我們上述方法表示的結果:
在這裏插入圖片描述
需要注意,這裏是按照層次遍歷來表示的(關於遍歷方式後面博客會繼續總結)

想象一下,既然是結構體,我們還可以存儲更多東西,例如在結點的結構體PTNode中接入孩子結點的位置,加入兄弟結點的位置,只要是便於樹的操作,完全可以開放性的設計!

2.2 雙親孩子表示法

結合雙親表示法,利用鏈式存儲,則有下面結構
在這裏插入圖片描述
分析完圖六,我們再來看雙親孩子表示法的實現:

#define MAX_TREE_SIZE 100

typedef char ElemType;

typedef struct CTNode
{
    int     child;  //孩子結點的下標
    struct  CTNode *next;  //指向孩子的指針
}*ChildPtr;

typedef struct ctbox
{
    ElemType  data;   //結點數據
    int       parent;   //結點下標
    ChildPtr  firstchild;  //指向第一個孩子的指針
}CTBox;

typedef struct pcTree
{
    CTBox nodes[MAX_TREE_SIZE];
    int r;
    int n;
}PCTree;

關於樹的其他知識,後續繼續總結!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章