广义表的复制详解(含C语言代码实现)
对于任意一个非空广义表来说,都是由两部分组成:表头和表尾。反之,只要确定的一个广义表的表头和表尾,那么这个广义表就可以唯一确定下来。
复制一个广义表,也是不断的复制表头和表尾的过程。如果表头或者表尾同样是一个广义表,依旧复制其表头和表尾。
所以,复制广义表的过程,其实就是不断的递归,复制广义表中表头和表尾的过程。
递归的出口有两个:
如果当前遍历的数据元素为空表,则直接返回空表。
如果当前遍历的数据元素为该表的一个原子,那么直接复制,返回即可。
还拿广义表 C 为例:
图1 广义表 C 的结构示意图
代码实现:
#include <stdio.h>#include <stdlib.h>typedef struct GLNode{int tag;//标志域union{char atom;//原子结点的值域struct{struct GLNode * hp,*tp;}ptr;//子表结点的指针域,hp指向表头;tp指向表尾};}*Glist,GNode;Glist creatGlist(Glist C){//广义表CC=(Glist)malloc(sizeof(GNode));C->tag=1;//表头原子‘a’C->ptr.hp=(Glist)malloc(sizeof(GNode));C->ptr.hp->tag=0;C->ptr.hp->atom='a';//表尾子表(b,c,d),是一个整体C->ptr.tp=(Glist)malloc(sizeof(GNode));C->ptr.tp->tag=1;C->ptr.tp->ptr.hp=(Glist)malloc(sizeof(GNode));C->ptr.tp->ptr.tp=NULL;//开始存放下一个数据元素(b,c,d),表头为‘b’,表尾为(c,d)C->ptr.tp->ptr.hp->tag=1;C->ptr.tp->ptr.hp->ptr.hp=(Glist)malloc(sizeof(GNode));C->ptr.tp->ptr.hp->ptr.hp->tag=0;C->ptr.tp->ptr.hp->ptr.hp->atom='b';C->ptr.tp->ptr.hp->ptr.tp=(Glist)malloc(sizeof(GNode));//存放子表(c,d),表头为c,表尾为dC->ptr.tp->ptr.hp->ptr.tp->tag=1;C->ptr.tp->ptr.hp->ptr.tp->ptr.hp=(Glist)malloc(sizeof(GNode));C->ptr.tp->ptr.hp->ptr.tp->ptr.hp->tag=0;C->ptr.tp->ptr.hp->ptr.tp->ptr.hp->atom='c';C->ptr.tp->ptr.hp->ptr.tp->ptr.tp=(Glist)malloc(sizeof(GNode));//存放表尾dC->ptr.tp->ptr.hp->ptr.tp->ptr.tp->tag=1;C->ptr.tp->ptr.hp->ptr.tp->ptr.tp->ptr.hp=(Glist)malloc(sizeof(GNode));C->ptr.tp->ptr.hp->ptr.tp->ptr.tp->ptr.hp->tag=0;C->ptr.tp->ptr.hp->ptr.tp->ptr.tp->ptr.hp->atom='d';C->ptr.tp->ptr.hp->ptr.tp->ptr.tp->ptr.tp=NULL;return C;}void copyGlist(Glist C, Glist *T){//如果C为空表,那么复制表直接为空表if (!C) {*T=NULL;}else{*T=(Glist)malloc(sizeof(GNode));//C不是空表,给T申请内存空间//申请失败,程序停止if (!*T) {exit(0);}(*T)->tag=C->tag;//复制表C的tag值//判断当前表元素是否为原子,如果是,直接复制if (C->tag==0) {(*T)->atom=C->atom;}else{//运行到这,说明复制的是子表copyGlist(C->ptr.hp, &((*T)->ptr.hp));//复制表头copyGlist(C->ptr.tp, &((*T)->ptr.tp));//复制表尾}}}int main(int argc, const char * argv[]) {Glist C=NULL;C=creatGlist(C);Glist T=NULL;copyGlist(C,&T);printf("%c",T->ptr.hp->atom);return 0;}
运行结果:
a
总结
在实现复制广义表的过程中,实现函数为:
void copyGlist(Glist C, Glist *T);
