C#数据结构-广义表和递归
生活随笔
收集整理的這篇文章主要介紹了
C#数据结构-广义表和递归
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
廣義表是線性表的推廣。定義是:一個廣義表是n個元素的一個有限序列。差不多就是線性表元素里面還有線性表,這個表里面的元素稱為原子,如果這個原子也是線性表稱之為子表。表示為:GL=(a1,a2,a3.....an)。和我們windows下面的文件、樹結構有點類似
特點:
1.一個廣義表種數據元素可以是原子,也可以是子表
2.廣義表的數據元素是有限個,數據元素有相對的順序
3.廣義表的長度定義為最外層包含的元素個數
4.廣義表的深度為所有括號的重數,如果原子深度為0,空表的深度為1
5.廣義表可以共享,這種廣義表稱為再入表
下面我們用圖和表示法讓大家理解: (1)A = (),A是一個空表,表的長度為0,沒有表頭和表尾。 (2)B = (a,b),B是一個只包括原子的表,稱為線性表,表的長度為2,表頭是a,表尾是(b)(表尾還是一個表,其表頭是b,表尾是空表())。 (3)C = (c,(d,e,f)),C是一個包括一個原子和一個子表的表,表的長度為2,表頭是c,表尾是((d,e,f))(表尾還是一個表,其表頭是(d,e,f),表尾是空表())。 (4)D = (B,C,A) = ((a,b),(c,(d,e,f)),()),D是一個包括三個子表的表,表的長度為3,表頭是B,表尾是(C,A)。 (5)E = (B,D) = ((a,b),(B,C,A)) = ((a,b),((a,b),(c,(d,e,f)),())),E是一個包括兩個子表的表,表的長度為2,表頭是B,表尾是(D)。 (6)F = (g,F) = (g,(g,(g,(…)))),F是一個包括一個原子和一個子表的表,表的長度為2,表頭是g,表尾是(F)(表尾還是一個表,其表頭是(F),表尾是空表()),對于表頭來說出現了遞歸。 在實現廣義表之前我們要了解一個東西,遞歸。因為廣義表和樹比較相似,所以樹那一塊用遞歸比較多。什么是遞歸?講的通俗點就是傳遞、回歸,舉個例子
static void Main(string[] args){Console.WriteLine(AddSums(3));Console.Read();}public static int AddSums(int i){return i <= 1 ? i : i + AddSums(i - 1);} 傳遞:瘋狂的調用AddSums(int i)這個函數 第一步:AddSums(3)-->3+AddSums(2) 第二步:AddSums(2)-->2+AddSums(1) 第三步:這里,我們發現i<=1是真,所以:AddSums(1)-->1
回歸:我們不能一直調這個函數,我們趕緊return回來
下面我們來創建廣義表:
class GLNode{//標簽,1:表和子表的表結構,0:原子節點public int tag;//原子值public char data;//子表指針public GLNode subList;//下一個元素public GLNode link;} 廣義表的操作,深度和長度,我們會發現這里的操作都是需要使用遞歸:
class GenTableClass{public GLNode head = new GLNode();//廣義表輸出字符串string glstr = string.Empty;#region 創建廣義表public void CreateGL(string str){int i = 0;head = CreateGL(str, ref i);}public GLNode CreateGL(string str, ref int i){GLNode h;char ch = str[i];i++;if (i < str.Length)//串開始{h = new GLNode();if (ch == '(')//子表開始{h.tag = 1;h.subList = CreateGL(str, ref i);}else if (ch == ')')//子表結束{h = null;}else if (ch == '#')//空表{h = null;}else//原子{h.tag = 0;h.data = ch;}}else//串結束{h = null;}if (i<str.Length){ch = str[i];i++;if (h!=null && ch==',')//兄弟結點{h.link = CreateGL(str, ref i);}else//沒有兄弟結點{h.link = null;}}return h;}#endregion#region 輸出廣義表public string DisGL(){string glStr = string.Empty;DisGL(head);return glStr;}private void DisGL(GLNode gl){ }#endregion#region 廣義表長度public int GetGLLength(){int len = 0;GLNode gl = head.subList;while (gl != null){len++;gl = gl.link;}return len;}#endregion#region 廣義表深度public int GLDepth(){return GLDepth(head);}public int GLDepth(GLNode gl){GLNode glnode;int max = 0, dep;//原子,輸出0if (gl.tag == 0){return 0;}glnode = gl.subList;//空表,輸出深度1if (glnode == null){return 1;}//遍歷廣義表所有元素while (glnode != null){if (glnode.tag == 1){//遞歸子表深度dep = GLDepth(glnode);if (dep > max){max = dep;}}glnode = glnode.link;}return (max + 1);}#endregion}
新人創作打卡挑戰賽發博客就能抽獎!定制產品紅包拿不停!
6.廣義表可以是一個遞歸表,遞歸表的深度是無限,長度是有限的
7.非空廣義表分為表頭(第一個元素)和表尾(第一個元素后面的元素),所以,空表是不可以求表頭表尾的下面我們用圖和表示法讓大家理解: (1)A = (),A是一個空表,表的長度為0,沒有表頭和表尾。 (2)B = (a,b),B是一個只包括原子的表,稱為線性表,表的長度為2,表頭是a,表尾是(b)(表尾還是一個表,其表頭是b,表尾是空表())。 (3)C = (c,(d,e,f)),C是一個包括一個原子和一個子表的表,表的長度為2,表頭是c,表尾是((d,e,f))(表尾還是一個表,其表頭是(d,e,f),表尾是空表())。 (4)D = (B,C,A) = ((a,b),(c,(d,e,f)),()),D是一個包括三個子表的表,表的長度為3,表頭是B,表尾是(C,A)。 (5)E = (B,D) = ((a,b),(B,C,A)) = ((a,b),((a,b),(c,(d,e,f)),())),E是一個包括兩個子表的表,表的長度為2,表頭是B,表尾是(D)。 (6)F = (g,F) = (g,(g,(g,(…)))),F是一個包括一個原子和一個子表的表,表的長度為2,表頭是g,表尾是(F)(表尾還是一個表,其表頭是(F),表尾是空表()),對于表頭來說出現了遞歸。 在實現廣義表之前我們要了解一個東西,遞歸。因為廣義表和樹比較相似,所以樹那一塊用遞歸比較多。什么是遞歸?講的通俗點就是傳遞、回歸,舉個例子
static void Main(string[] args){Console.WriteLine(AddSums(3));Console.Read();}public static int AddSums(int i){return i <= 1 ? i : i + AddSums(i - 1);} 傳遞:瘋狂的調用AddSums(int i)這個函數 第一步:AddSums(3)-->3+AddSums(2) 第二步:AddSums(2)-->2+AddSums(1) 第三步:這里,我們發現i<=1是真,所以:AddSums(1)-->1
回歸:我們不能一直調這個函數,我們趕緊return回來
第四步:輸出AddSums(1)
第四步:這里AddSums(1)我們知道是等于1的,那么AddSums(2)是不是就是2+1 第五步:AddSums(3)是不是3+上面的2+1,return 3+3下面我們來創建廣義表:
class GLNode{//標簽,1:表和子表的表結構,0:原子節點public int tag;//原子值public char data;//子表指針public GLNode subList;//下一個元素public GLNode link;} 廣義表的操作,深度和長度,我們會發現這里的操作都是需要使用遞歸:
class GenTableClass{public GLNode head = new GLNode();//廣義表輸出字符串string glstr = string.Empty;#region 創建廣義表public void CreateGL(string str){int i = 0;head = CreateGL(str, ref i);}public GLNode CreateGL(string str, ref int i){GLNode h;char ch = str[i];i++;if (i < str.Length)//串開始{h = new GLNode();if (ch == '(')//子表開始{h.tag = 1;h.subList = CreateGL(str, ref i);}else if (ch == ')')//子表結束{h = null;}else if (ch == '#')//空表{h = null;}else//原子{h.tag = 0;h.data = ch;}}else//串結束{h = null;}if (i<str.Length){ch = str[i];i++;if (h!=null && ch==',')//兄弟結點{h.link = CreateGL(str, ref i);}else//沒有兄弟結點{h.link = null;}}return h;}#endregion#region 輸出廣義表public string DisGL(){string glStr = string.Empty;DisGL(head);return glStr;}private void DisGL(GLNode gl){ }#endregion#region 廣義表長度public int GetGLLength(){int len = 0;GLNode gl = head.subList;while (gl != null){len++;gl = gl.link;}return len;}#endregion#region 廣義表深度public int GLDepth(){return GLDepth(head);}public int GLDepth(GLNode gl){GLNode glnode;int max = 0, dep;//原子,輸出0if (gl.tag == 0){return 0;}glnode = gl.subList;//空表,輸出深度1if (glnode == null){return 1;}//遍歷廣義表所有元素while (glnode != null){if (glnode.tag == 1){//遞歸子表深度dep = GLDepth(glnode);if (dep > max){max = dep;}}glnode = glnode.link;}return (max + 1);}#endregion}
新人創作打卡挑戰賽發博客就能抽獎!定制產品紅包拿不停!
總結
以上是生活随笔為你收集整理的C#数据结构-广义表和递归的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: JavaScript函数式编程入门经典
- 下一篇: C#数据结构-双链表