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