標籤:c# 資料結構 樹 datastructure
樹(Tree)是n(n>=0)個相同類型的資料元素的有限集合。樹中的資料元素叫結點(Node)。n=0的樹稱為空白樹(Empty Tree);對於n>0的任意非空樹T有:
1.有且只有一個特殊的結點稱為樹的根(Root)結點,根沒有前驅結點。
2.若n>1,則除根結點外,其餘結點被分成了m(m>0)個互不相交的集合T1,T2,T3,...Tm,其中每個集合Ti(1<=i<=m)本身又是一棵樹。樹T1,T2,...Tm稱為這棵樹的子樹(Subtree)。
由樹的定義可知,樹的定義是遞迴的,用樹來定義樹,因此,樹的許多運算都使用過了遞迴。
樹的相關術語
結點(Node)。表示樹中的資料元素,由資料項目和資料元素之間的關係組成。
結點的度。結點所擁有的子樹的個數。
樹的度。樹中各結點度的最大值。
葉子結點。度為0的結點,也叫終端結點。
其他術語參考二叉樹。
用多重鏈表標記法儲存樹
每個結點指標域的個數等於樹的度數。
using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace DataStructure{ public interface ITree<T> { T Root(); //求樹的根結點 T Parent(T t); //求結點t的雙親結點 T Child(T t, int i); //求結點t的第i個子結點 T RightSibling(T t); //求結點t第一個右邊兄弟結點 bool Insert(T s, T t, int i); //將樹s加入樹中作為結點t的第i顆子樹 T Delete(T t, int i); //刪除結點t的第i顆子樹 void Traverse(int TraverseType); //按某種方式遍曆樹 void Clear(); //清空樹 bool IsEmpty(); //判斷是否為空白 int GetDepth(T t); //求樹的深度 } /// <summary> /// 迴圈順序隊列 /// </summary> /// <typeparam name="T"></typeparam> class CSeqQueue<T> { private int maxsize; //迴圈順序隊列的容量 private T[] data; //數組,用於儲存迴圈順序隊列中的資料元素 private int front; //指示最近一個已經離開隊列的元素所佔有的位置 迴圈順序隊列的對頭 private int rear; //指示最近一個進入隊列的元素的位置 迴圈順序隊列的隊尾 public T this[int index] { get { return data[index]; } set { data[index] = value; } } //容量屬性 public int Maxsize { get { return maxsize; } set { maxsize = value; } } //對頭指標屬性 public int Front { get { return front; } set { front = value; } } //隊尾指標屬性 public int Rear { get { return rear; } set { rear = value; } } public CSeqQueue() { } public CSeqQueue(int size) { data = new T[size]; maxsize = size; front = rear = -1; } //判斷迴圈順序隊列是否為滿 public bool IsFull() { if ((front == -1 && rear == maxsize - 1) || (rear + 1) % maxsize == front) return true; else return false; } //清空迴圈順序列表 public void Clear() { front = rear = -1; } //判斷迴圈順序隊列是否為空白 public bool IsEmpty() { if (front == rear) return true; else return false; } //入隊操作 public void EnQueue(T elem) { if (IsFull()) { Console.WriteLine("Queue is Full !"); return; } rear = (rear + 1) % maxsize; data[rear] = elem; } //出隊操作 public T DeQueue() { if (IsEmpty()) { Console.WriteLine("Queue is Empty !"); return default(T); } front = (front + 1) % maxsize; return data[front]; } //擷取對頭資料元素 public T GetFront() { if (IsEmpty()) { Console.WriteLine("Queue is Empty !"); return default(T); } return data[(front + 1) % maxsize];//front從-1開始 } //求迴圈順序隊列的長度 public int GetLength() { return (rear - front + maxsize) % maxsize; } } /// <summary> /// 樹的多鏈表結點類 /// </summary> /// <typeparam name="T"></typeparam> class MLNode<T> { private T data; //儲存結點的資料 private MLNode<T>[] childs; //儲存子結點的位置 public MLNode(int max) { childs = new MLNode<T>[max]; for (int i = 0; i < childs.Length; i++) { childs[i] = null; } } public T Data { get { return data; } set { data = value; } } public MLNode<T>[] Childs { get { return childs; } set { childs = value; } } } class MLTree<T> : ITree<MLNode<T>> { private MLNode<T> head; public MLNode<T> Head { get { return head; } set { head = value; } } public MLTree() { head = null; } public MLTree(MLNode<T> node) { head = node; } //求樹的根結點 public MLNode<T> Root() { return head; } public void Clear() { head = null; } //待測試!!! public int GetDepth(MLNode <T> root) { int len; if (root == null) { return 0; } for (int i = 0; i < root.Childs.Length; i++) { if (root.Childs[i] != null) { len = GetDepth(root.Childs[i]); return len + 1; } } return 0; } public bool IsEmpty() { return head == null; } //求結點t的雙親結點,如果t的雙親結點存在,返回雙親結點,否則返回空 //按層序遍曆的演算法進行尋找 public MLNode<T> Parent(MLNode<T> t) { MLNode<T> temp = head; if (IsEmpty() || t == null) return null; if (temp.Data.Equals(t.Data)) return null; CSeqQueue<MLNode<T>> queue = new CSeqQueue<MLNode<T>>(50); queue.EnQueue(temp); while (!queue.IsEmpty()) { temp = (MLNode<T>)queue.DeQueue(); for (int i = 0; i < temp.Childs.Length; i++) { if (temp.Childs[i] != null) { if (temp.Childs[i].Data.Equals(t.Data)) { return temp; } else { queue.EnQueue(temp.Childs[i]); } } } } return null; } //求結點t的第i個子結點。如果存在,返回第i個子結點,否則返回空 //i=0時,表示求第一個子節點 public MLNode<T> Child(MLNode<T> t, int i) { if (t != null && i < t.Childs.Length) { return t.Childs[i]; } else { return null; } } //求結點t第一個右邊兄弟結點,如果存在,返回第一個右邊兄弟結點,否則返回空 public MLNode<T> RightSibling(MLNode<T> t) { MLNode<T> pt = Parent(t); if (pt != null) { int i = FindRank(t); return Child(pt, i + 1); } else { return null; } } //尋找結點t在兄弟中的排行,成功時返回位置,否則返回-1 private int FindRank(MLNode<T> t) { MLNode<T> pt = Parent(t); for (int i = 0; i < pt.Childs.Length; i++) { MLNode<T> temp = pt.Childs[i]; if (temp != null && temp.Data.Equals(t.Data)) { return i; } } return -1; } //尋找在樹中的結點t,成功是返回t的位置,否則返回null private MLNode<T> FindNode(MLNode<T> t) { if (head.Data.Equals(t.Data)) return head; MLNode<T> pt = Parent(t); foreach (MLNode<T> temp in pt.Childs) { if (temp != null && temp.Data.Equals(t.Data)) { return temp; } } return null; } //把以s為頭結點的樹插入到樹中作為結點t的第i顆子樹。成功返回true public bool Insert(MLNode<T> s, MLNode<T> t, int i) { if (IsEmpty()) head = t; t = FindNode(t); if (t != null && t.Childs.Length > i) { t.Childs[i] = s; return true; } else { return false; } } //刪除結點t的第i個子樹。返回第i顆子樹的根結點。 public MLNode<T> Delete(MLNode<T> t, int i) { t = FindNode(t); MLNode<T> node = null; if (t != null && t.Childs.Length > i) { node = t.Childs[i]; t.Childs[i] = null; } return node; } //先序遍曆 //根結點->遍曆根結點的左子樹->遍曆根結點的右子樹 public void preorder(MLNode<T> root) { if (root == null) return; Console.WriteLine(root.Data + " "); for (int i = 0; i < root.Childs.Length; i++) { preorder(root.Childs[i]); } } //後序遍曆 //遍曆根結點的左子樹->遍曆根結點的右子樹->根結點 public void postorder(MLNode<T> root) { if (root == null) { return; } for (int i = 0; i < root.Childs.Length; i++) { postorder(root.Childs[i]); } Console.WriteLine(root.Data + " "); } //層次遍曆 //引入隊列 public void LevelOrder(MLNode<T> root) { Console.WriteLine("遍曆開始:"); if (root == null) { Console.WriteLine("沒有結點!"); return; } MLNode<T> temp = root; CSeqQueue<MLNode<T>> queue = new CSeqQueue<MLNode<T>>(50); queue.EnQueue(temp); while (!queue.IsEmpty()) { temp = (MLNode<T>)queue.DeQueue(); Console.WriteLine(temp.Data + " "); for (int i = 0; i < temp.Childs.Length; i++) { if (temp.Childs[i] != null) { queue.EnQueue(temp.Childs[i]); } } } Console.WriteLine("遍曆結束!"); } //按某種方式遍曆樹 //0 先序 //1 後序 //2 層序 public void Traverse(int TraverseType) { if (TraverseType == 0) preorder(head); else if (TraverseType == 1) postorder(head); else LevelOrder(head); } } class Tree { static void Main(string[] args) { MLTree<string> tree = new MLTree<string>(); char ch; do { Console.WriteLine("1.添加結點"); Console.WriteLine("2.刪除結點"); Console.WriteLine("3.遍曆樹"); Console.WriteLine("4.添加子結點"); Console.WriteLine("5.退出"); Console.WriteLine(); ch = Convert.ToChar(Console.ReadLine()); switch (ch) { case '1': Console.WriteLine("輸入父結點:"); string str = Convert.ToString(Console.ReadLine()); MLNode<string> pt = new MLNode<string>(4); pt.Data = str; Console.WriteLine("輸入子結點:"); str = Convert.ToString(Console.ReadLine()); MLNode<string> ct = new MLNode<string>(4); ct.Data = str; Console.WriteLine("輸入插入子結點的位置:"); int i = Convert.ToInt32(Console.ReadLine()); bool ok = tree.Insert(ct, pt, i); if (ok) { Console.WriteLine("插入{0}成功", ct.Data); Console.WriteLine(tree.GetDepth(pt)); } break; case '2': Console.WriteLine("輸入要刪除的結點:"); str = Convert.ToString(Console.ReadLine()); pt = new MLNode<string>(4); pt.Data = str; tree.Delete(pt, 0); break; case '3': tree.Traverse(2); break; } } while (ch != '5'); } }}
C#資料結構-樹 data Structure Tree