广义表是线性表的推广。定义是:一个广义表是n个元素的一个有限序列。差不多就是线性表元素里面还有线性表,这个表里面的元素称为原子,如果这个原子也是线性表称之为子表。表示为:GL=(a1,a2,a3.....an)。和我们windows下面的文件、树结构有点类似
特点:
1.一个广义表种数据元素可以是原子,也可以是子表
2.广义表的数据元素是有限个,数据元素有相对的顺序
3.广义表的长度定义为最外层包含的元素个数
4.广义表的深度为所有括号的重数,如果原子深度为0,空表的深度为1
5.广义表可以共享,这种广义表称为再入表
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;
//原子,输出0
if (gl.tag == 0)
{
return 0;
}
glnode = gl.subList;
//空表,输出深度1
if (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
}