就快考数据结构了 复习中,之前写过一篇广义表的 是用头尾结点表示法实现的,这次的是用兄弟孩子结点表示法实现的,相比之下,这种表示法的要简洁的。虽然考试这方面的应该不考多少,但是兴趣所在,以后学LISP的话 也有点基础。 之前写的广义表
//头文件
#include <iostream>
using namespace std;
//广义表存储结构
struct GL_Node
{
int tag;
union {
char data; //原子值
GL_Node *sublist; //指向子表的指针
} val;
GL_Node *link;
};
int GL_Length(GL_Node *G)
{
//G为广义表表头节点指针
int n=0;
G=G->val.sublist;
while(G)
{
n++;
G=G->link;
}
return n;
}
int GL_Depth(GL_Node *G)
{
int max=0,dep;
if(G->tag == 0)
return 0;
G=G->val.sublist;
if(!G)
return 1;
while(G)
{
if(G->tag == 1)
{
dep=GL_Depth(G);
if(dep > max)
max=dep;
}
G=G->link;
}
return (max+1);
}
GL_Node *GL_CreateGL(char *&s)
{
GL_Node *h;
char ch;
ch=*s; //取一个扫描字符
s++; //指向下一个待扫描字符
if(ch != '\0')
{
h=new GL_Node;
if(ch == '(')
{
h->tag=1;
h->val.sublist=GL_CreateGL(s); //递归构造子表
}
else if(ch == ')')
h=NULL; //右括号时,子表为空
else
{
h->tag=0;
h->val.data=ch;
}
}
else
h=NULL;
ch=*s;
s++;
if(h)
{
if(ch == ',') //递归构造后序子表
h->link=GL_CreateGL(s);
else
h->link=NULL;
}
return h;
}
void GL_Display(GL_Node *G)
{
if(G)
{
if(G->tag == 1)
{
cout<<"(";
if(G->val.sublist)
GL_Display(G->val.sublist); //递归输出子表
else
cout<<"";
}
else
cout<<G->val.data;
if(G->tag == 1)
cout<<")";
if(G->link)
{
cout<<",";
GL_Display(G->link);
}
}
}
GL_Node *GL_Copy(GL_Node *G)
{
//复制广义表
GL_Node *Q;
if(!G)
return NULL;
Q=new GL_Node;
Q->tag=G->tag;
if(G->tag == 1)
Q->val.sublist=GL_Copy(G->val.sublist);
else
Q->val.data=G->val.data;
Q->link=GL_Copy(G->link);
return Q;
}
//取表头
GL_Node *Get_Head(GL_Node *G)
{
GL_Node *p=G->val.sublist;
GL_Node *q,*t;
if(!p)
{
cout<<"空表无法求表头"<<endl;
return NULL;
}
else if(G->tag == 0)
{
cout<<"原子结点无法求表头"<<endl;
return NULL;
}
if(p->tag == 0)
{
q=new GL_Node;
q->tag=0;
q->val.data=p->val.data;
q->link=NULL;
}
else
{
t=new GL_Node;
t->tag=1;
t->val.sublist=p->val.sublist;
t->link=NULL;
q=GL_Copy(t);
delete t;
}
return q;
}
//取表尾
GL_Node *Get_Tail(GL_Node *G)
{
GL_Node *p=G->val.sublist;
GL_Node *q,*t;
if(!G)
{
cout<<"空表不能求表尾"<<endl;
return NULL;
}
else if(G->tag == 0)
{
cout<<"原子结点不能求表尾"<<endl;
return NULL;
}
p=p->link;
t=new GL_Node;
t->tag=1;
t->link=NULL;
t->val.sublist=p;
q=GL_Copy(t);
delete t;
return q;
}
void Replace(GL_Node *&G,char x,char y)
{
GL_Node *p,*q;
p=G->val.sublist;
while(p)
{
if(p->tag == 0)
{
if(p->val.data == x)
p->val.data=y;
}
else
Replace(p,x,y);
p=p->link;
}
}
void GL_Insert(GL_Node *&G,char x,char y)
{
//在广义表中元素x的后面插入y,有多个x时,插在每一个后面
if(!G)
return;
GL_Node *p=G->val.sublist;
GL_Node *q=NULL;
while(p)
{
if(p->tag == 0)
{
if(p->val.data == x)
{
q=new GL_Node;
q->tag=0;
q->val.data=y;
q->link=p->link;
p->link=q;
cout<<"插如成功"<<endl;
}
}
else
GL_Insert(p,x,y);
p=p->link;
}
}
void GL_Delete(GL_Node *&G,char x)
{
//在广义表中删除x,有多个,就全部删除
GL_Node *p,*q;
if(!G)
return;
p=G->val.sublist;
q=NULL;
while(p)
{
if(p->tag == 0)
{
if(p->val.data == x)
{
if(!q) //说明该结点是该子表的第一个元素
{
G->val.sublist=p->link;
delete p;
//删完一个之后,要给p赋上合适的值,使得程序可以继续递归删除
p=G->val.sublist;
continue;
}
else
{
q->link=p->link;
delete p;
//删完一个之后,要给p赋上合适的值,使得程序可以继续递归删除
p=q->link;
continue;
}
cout<<"删除成功"<<endl;
}
else
q=p;
}
else
{
GL_Delete(p,x);
q=p; //保证程序在递归返回之后,q的位置在p前面,保证删除操作正确,核心的一句。
}
p=p->link;
}
}
主函数
#include "glist.h"
int main()
{
char *s="(a,(b,c,d),(d,l),d,p))";
GL_Node *G;
G=GL_CreateGL(s);
cout<<"表的深度为:"<<GL_Depth(G)<<endl;
cout<<"表的长度为:"<<GL_Length(G)<<endl;
cout<<"遍历表:";
GL_Display(G);
cout<<endl;
GL_Node *H,*T;
H=Get_Head(G);
cout<<"表的表头为:";
GL_Display(H);
cout<<endl;
cout<<"表尾为:";
T=Get_Tail(G);
GL_Display(T);
cout<<endl;
cout<<"将原表中的d全部替换成k"<<endl;
Replace(G,'d','k');
GL_Display(G);
cout<<endl;
cout<<"在k后面插入x"<<endl;
GL_Insert(G,'k','x');
GL_Display(G);
cout<<endl;
cout<<"删除表中数据'k'"<<endl;
GL_Delete(G,'k');
GL_Display(G);
cout<<endl;
return 0;
}
测试结果
其中测试的表是
(a,(b,c,d),(d,l),d,p))
表的深度为:2
表的长度为:5
遍历表:(a,(b,c,d),(d,l),d,p)
表的表头为:a
表尾为:((b,c,d),(d,l),d,p)
将原表中的d全部替换成k
(a,(b,c,k),(k,l),k,p)
在k后面插入x
插如成功
插如成功
插如成功
(a,(b,c,k,x),(k,x,l),k,x,p)
删除表中数据'k'
(a,(b,c,x),(x,l),x,p)
Press any key to continue