树 ---树
樹的定義
樹(Tree)是N(N>=0)個結點的有限集。當N=0時成為空樹,在任意一棵非空樹種:
-有且僅有一個特定的成為根(Root)的結點。
-當N>1時,其余結點可分為m(m>0)個互不相交的有限集T1,T2...Tm,其中每一個集合本身又是一棵樹,并且成為根的子樹(SubTree)。
 
雖然從概念上很容易理解樹,但是有兩點還是需要大家注意下
-n>0時,根結點是唯一的,堅決不可能存在多個根結點。
-m>0時,子樹的個數是沒有限制的,但他們互相是一定不會相交的。
結點分類
上圖中,每一個圈圈我們就稱為樹的一個結點。結點擁有的子樹稱為結點的度-(Degree),樹的度取樹內各結點的度的最大值。
-度為0的結點稱為葉結點(Leaf)或終端結點。
-度不為0的結點稱為分支結點或非終端結點,除根結點外,分支結點也稱為內部結點。
 
結點間的關系
結點的子樹的根稱為結點的孩子(Child),相應的,該結點稱為孩子的雙親(Parent),同一雙親的孩子之間互稱為兄弟(Sibling)。
結點的祖先是從根到該結點所經分支上的所有結點。
 
其他概念
如果將樹中結點的各子樹看成從左至右是有次序的,不能互換的,則稱該樹為有序樹,否則稱為無序樹。
森林是m(m>=0)棵互不相交的樹的集合。對樹種每個結點而言,其子樹的集合即為森林。
結點的層次
結點的層次(Level)從根開始定一起,根為第一層,根的孩子為第二層,
其雙親在同一層的結點互為堂兄弟。
樹中結點的最大層次稱為樹的深度(Depth)或高度。
 
 
樹的存儲結構
要存儲樹,簡單的順序存儲結構和鏈式存儲結構是不能的,不過如果充分利用它們各自的特點,完全可以間接地來實現。要考慮到雙親,孩子,兄弟之間的關系。
這里介紹三種不同的表示法:雙親表示法,孩子表示法,孩子兄弟表示法。
雙親表示法
言外之意就是以雙親作為索引的關鍵詞的一種存儲方式。
我們假設以一組連續控件存儲樹的結點,同事在每個結點中,附設一個指示其雙親結點在數組中位置的元素。也就是說,每個結點除了知道自己是誰之外,還要知道它的爸爸媽媽在哪里。
 
 
 
這樣的存儲結構,我們可以根據某結點的parent指針找到它的雙親結點,所用的時間復雜度是O(1),索引到parent的值為-1時,表示找到了樹結點的根。
可是如果我們要知道某節點的孩子是什么?那么不好意思,請遍歷整個樹結構。能不能改進一下呢?
當然,我們可以這樣改進下:
 
那如果我們又比較它們兄弟之間的關系呢?
 
 
存儲結構的設計是一個非常靈活的過程,只要你愿意,你可以設計出任何你想要的結構。
一個存儲結構設計的是否合理,取決于基于該存儲結構的運算是否適合,是否方便,時間復雜度好不好等等。
孩子表示法
這里給出一共三種方案,第一種:根據樹的度,聲明足夠空間存放子樹指針指針的節點。
 
但是這種方式呢,很明顯造成資源的浪費。
針對方案一的缺點,我們有了方案二:
 
這樣我們就克服了浪費這個概念,我們從此走上了節儉的社會主義道路,但每個節點的度的值不同,初始化和維護起來難度巨大,結構動態很復雜,花費了更多的時間。
下面這一種即節省了空間又節省了時間。
 
這種是數組和鏈表的搭配構成。但是上面只能找到孩子,找不到雙親貌似還不夠完善,那么合并雙親孩子表示法:
 
那么在最后還有一種孩子兄弟表示法,構造方式也是大同小異,不多做解釋,大家可以來思考。
那么上代碼來寫結構:
 
總結
 
                            
                        - 上一篇: docker web程序本地化_dock
- 下一篇: 展望未来电力行业发展
