广义表-求广义表深度,建立广义表,复制广义表
例:
广义表(a,(a,b),d,e,((i,j),k)) 求广义表的长度和深度
长度为5,深度为3
长度:有效逗号个数+1
深度:有效括号个数
求广义表的深度
广义表的深度指的是广义表中括弧的重数;
空表的深度为1,因为有一对括弧;
原子的深度为0;
解题思路:
1)遍历该广义表各个数据元素,求该元素的深度。如果该元素是原子,则返回深度0;如果该元素是子表,则遍历该子表的深度;
2)递归的出口状态,或者叫做终结状态:当遍历数据元素为原子时返回0,当遍历数据元素为空表时,返回1;
3)设置一个变量max用来记录数据元素中最长的深度;初始化max=0;遍历过程中max与返回的整型值进行比较,取值较大的那一个。直到程序结束。max+1就是广义表的深度;
代码
int GetGListDepth(GList L){ if(!L) return 1; if(L->tag==0) return 0; for(int max=0, pp=L;pp;pp=pp->ptr.tp){ dep=GetGListDepth(pp->ptr.hp); if(dep>max) max=dep; } return max+1 //非空表的深度是各元素深度最大值加1 }
复制广义表
任何一个非空的广义表均可分解成表头和表尾。反之,一对确定的表头和表尾可唯一确定一个广义表。
由此,复制一个广义表只要分别复制其表头和表尾,然后合成即可。
复制一个广义表,也是不断的复制表头和表尾的过程。如果表头或者表尾同样是一个广义表,依旧复制其表头和表尾。
所以,复制广义表的过程,其实就是不断的递归,复制广义表中表头和表尾的过程。
递归的出口条件:
如果当前遍历的数据元素为空表,则直接返回空表。
如果当前遍历的数据元素为该表的一个原子,那么直接复制,返回即可。
代码实现:
Status CopyGList(GList &T, GList L){ if(!L) T=NULL; //直接返回空表 else{ if(!(T=(GList)malloc(sizeof(GLNode)))) exit(OVERFLOW); //如果L不是空表,给T分配内存空间 T->tag=L->tag; if(L->tag ==ATOM) T->atom=L->atom; //直接复制原子 else { CopyGList(T->ptr.hp, L->ptr.hp); //复制表头 CopyGList(T->ptr.tp, L->ptr.tp); //复制表尾 } } return OK; }
建立广义表的存储结构
typedef struct GLNode{ int tag;//标志域 union{ int atom;//原子结点的值域 struct GLNode *hp;//子表结点的指针域,hp指向表头 }; struct GLNode * tp;//这里的tp相当于链表的next指针,用于指向下一个数据元素 }*Glist