广义表(C++实现)

广义表在学稀疏矩阵之后就应该学的,只是那时觉得看起来晕晕就跳过了,现在回头学了一下,觉得还是不错的一种结构。下面是代码:

文件"glist.h"

#include<iostream> #include<string> using namespace std; enum elemTag {ATOM,LIST}; class GList; class GLnode { private: elemTag Tag; //标志是原子还是子表 0:原子 1:子表 union { char data; //原子结点值域 struct //表结点指针域 { GLnode *hp; GLnode *tp; }ptr; }; friend class GList; }; class GList { public: string Decompose(string &str) { //将非空串str分割成2部分,hstr为第一个','之前的子串,str为后面的 int n,i,k; string ch,hstr; n=str.length(); for(i=0,k=-1;i<n && (ch!="," || k!=0) ;i++) { //搜索最外层第一个逗号 ch=str.substr(i,1); //从第i个位置起读1个字符 if(ch=="(") ++k; else if(ch==")") --k; } if(i<n) { hstr=str.substr(1,i-2);//不要左括号,不要逗号,所以是i-2 str="("+str.substr(i,n-i); } else { hstr=str.substr(1,n-2); str=""; } return hstr; } /*---------------------------------------------------- /从广义表书写形式串S创建采用头尾链表存储表示的广义表T /建立广义表头尾结点存储结构的递归定义: /基本项:当S为空串时,置空广义表 / 当S为单字符串时,建立原子结点的子表 /递归项:假设sub为脱去S最外层括号的子串,记为"s1,s2,s3,..,sn" / 每个si为非空字符串,对每个si建立一个表结点 /--------------------------------------------------------*/ void Create_GList(GLnode *&GL,string S) //创建广义表 { string hsub; if(S=="()") //S为空串 { GL=NULL; } else { GL=new GLnode; if(S.length()==1) { GL->Tag=ATOM; GL->data=S[0]; } else { GL->Tag=LIST; hsub=Decompose(S); //从S中分离出表头串hsub Create_GList(GL->ptr.hp,hsub); if(S.empty()) { GL->ptr.tp=NULL; } else { Create_GList(GL->ptr.tp,S); } } } } int GList_Depth(GLnode *GL) //求广义表深度 { /*----------------------------------------- /当广义表为空表时,深度为1,当广义表为原子时 /深度为0,当广义表为广义表时,深度的求法为 /GList_Depth(GL)=1+max{GList_Depth(lsi)} /-----------------------------------------*/ if(!GL) return 1; if(GL->Tag==ATOM) return 0; int dep,max; GLnode *p; for(max=0,p=GL;p;p=p->ptr.tp) { dep=GList_Depth(p->ptr.hp); if(dep>max) max=dep; } return 1+max; } void Copy_GList(GLnode *GL,GLnode *&T) //T复制GL { //当表为空时,复制空表,否则先复制表头在复制表尾 if(!GL) T=NULL; else { T=new GLnode; T->Tag=GL->Tag; if(GL->Tag==ATOM) T->data=GL->data; else { Copy_GList(GL->ptr.hp,T->ptr.hp); Copy_GList(GL->ptr.tp,T->ptr.tp); } } } /*----------------------------------------------- /遍历广义表,如果是空表就输出"()",如果遇到Tag=0 /的结点,则直接输出该结点的值,如果tag=1,说明 /是一个子表,首先输出左括号,然后递归调用输出数据 /元素,并当表尾不空的时候输出逗号,最后输出右括号 /-----------------------------------------------*/ void Traverse_GList(GLnode *L) { if(!L) cout<<"()"; else { if(L->Tag==ATOM) cout<<L->data; else { GLnode *p=NULL; cout<<'('; p=L; while(p) { Traverse_GList(p->ptr.hp); p=p->ptr.tp; if(p) cout<<','; } cout<<')'; } } } void GetHead(GLnode *GL) //取表头 { //取广义表第一个元素 cout<<"广义表:"; Traverse_GList(GL); cout<<endl; if(!GL || GL->Tag==0 ) cout<<"原子和空表不能去表头"<<endl; else { GLnode *h=GL->ptr.hp; if(h->Tag==ATOM) cout<<"表头为:"<<h->data<<endl; else { cout<<"表头为:"; Traverse_GList(h); cout<<endl; } } } void GetTail(GLnode *GL) //取表尾 { //广义表表尾指的是除了第一个元素后所有剩余的元素组成的表 cout<<"广义表:"; Traverse_GList(GL); cout<<endl; if(!GL || GL->Tag==0) cout<<"原子和空表不能取表尾"<<endl; else { GLnode *t; t=GL->ptr.tp; cout<<"表尾为:"; Traverse_GList(t); cout<<endl; } } int Length_GList_1(GLnode *GL) //求表长,非递归 { //用非递归方式求广义表长度 int len=0; if(GL && GL->Tag==LIST) { while(GL) { GL=GL->ptr.tp; len++; } return len; } else return 0; } int Length_GList_2(GLnode *GL) //求表长,递归 { if(!GL) return 0; return 1+Length_GList_2(GL->ptr.tp); } void Replace_GList(GLnode *p,char x,char y,GLnode *&q) //替换 { //将广义表p中元素x替换成y,构建新广义表q if(!p) q=NULL; else { if(p->Tag==ATOM) { q=new GLnode; q->Tag=ATOM; q->ptr.hp=NULL; if(p->data==x) q->data=y; else q->data=p->data; } else { GLnode *h,*t; Replace_GList(p->ptr.hp,x,y,h);//递归处理表头得到h Replace_GList(p->ptr.tp,x,y,t);//递归处理表尾得到t q=new GLnode; q->Tag=LIST; q->ptr.hp=h; q->ptr.tp=t; } } } int Is_Same(GLnode *p,GLnode *q)//判断是否相等 { int flag=1;//1表示相等,0表示不相等 if(p && q) { if(p->Tag==ATOM && q->Tag==ATOM) { if(p->data!=q->data) flag=0; else flag=1; } else if(p->Tag==LIST &&q->Tag==LIST) flag=Is_Same(p->ptr.hp,q->ptr.hp); else flag=0; if(flag) flag=Is_Same(p->ptr.tp,q->ptr.tp); } else { if(p && !q) flag=0; if(!p && q) flag=0; } return flag; } void Concat_Glist(GLnode *&GL,GLnode *LG) //连接两个广义表 { GLnode *p=GL; GLnode *q=p->ptr.tp; while(q->ptr.tp) q=q->ptr.tp; q->ptr.tp=LG; GL=p; } };

测试函数"main.cpp"

#include"glist.h" int main() { GList list; GLnode *GL=NULL; string S; cout<<"输入广义表S:"; cin>>S; list.Create_GList(GL,S); cout<<"广义表S的深度为:"<<list.GList_Depth(GL)<<endl; cout<<"广义表S的长度为:"<<list.Length_GList_1(GL)<<endl; cout<<"广义表S的长度为:"<<list.Length_GList_2(GL)<<endl; list.GetHead(GL); list.GetTail(GL); GLnode *T; cout<<"复制广义表"<<endl; list.Copy_GList(GL,T); cout<<"遍历复制后的广义表T"<<endl; list.Traverse_GList(T); cout<<endl; string F; cout<<"输入广义表F:"; cin>>F; GList list1; GLnode *LG; list1.Create_GList(LG,F); if(list.Is_Same(GL,LG)) cout<<"广义表S和F相等"<<endl; else cout<<"广义表S和F不相等"<<endl; cout<<"广义表F的长度为:"<<list1.Length_GList_2(LG)<<endl; char x,y; cout<<"输入你要替换的字符: "; cin>>x; cout<<endl; cout<<"输入你要替换成哪个字符:"; cin>>y; GLnode *k; list1.Replace_GList(LG,x,y,k); cout<<"替换后的广义表为:"; list1.Traverse_GList(k); cout<<endl; cout<<"连接广义表S与被替换字符后的广义表F的表为:"; list.Concat_Glist(GL,k); list.Traverse_GList(GL); cout<<endl; return 0; }

下面是输出结果

输入广义表S:((a,b),(c,d)) 广义表S的深度为:2 广义表S的长度为:2 广义表S的长度为:2 广义表:((a,b),(c,d)) 表头为:(a,b) 广义表:((a,b),(c,d)) 表尾为:((c,d)) 复制广义表 遍历复制后的广义表T ((a,b),(c,d)) 输入广义表F:(f,(g,h),(i,i)) 广义表S和F不相等 广义表F的长度为:3 输入你要替换的字符: i 输入你要替换成哪个字符:x 替换后的广义表为:(f,(g,h),(x,x)) 连接广义表S与被替换字符后的广义表F的表为:((a,b),(c,d),f,(g,h),(x,x)) Press any key to continue


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值