_DataStructure_C_Impl:广义表的扩展线性链表存储

来源:互联网 发布:程序员网上接项目 编辑:程序博客网 时间:2024/06/05 15:52
#include<stdio.h>#include<stdlib.h>#include<string.h>#include"SeqString.h"typedef char AtomType;typedef enum{ATOM,LIST} ElemTag;//ATOM=0,表示原子,LIST=1,表示子表typedef struct GLNode{ElemTag tag;//标志位tag用于区分元素是原子还是子表union{AtomType atom;//AtomType是原子结点的值域,用户自己定义类型struct GLNode *hp;//hp指向表头,tp指向表尾}ptr;struct GLNode *tp;}*GList,GLNodeList;//求广义表的表头结点操作GLNodeList* GetHead(GList L){GLNodeList *p;p=L->ptr.hp; /*将广义表的表头指针赋值给p*/if(!p) /*如果广义表为空表,则返回1*/{printf("该广义表是空表!");return NULL;}else if(p->tag==LIST)printf("该广义表的表头是非空的子表。");elseprintf("该广义表的表头是原子。");return p;}//求广义表的表尾操作GLNodeList *GetTail(GList L){GLNodeList *p,*tail;p=L->ptr.hp;if(!p) /*如果广义表为空表,则返回1*/{printf("该广义表是空表!");return NULL;}tail=(GLNodeList*)malloc(sizeof(GLNodeList));/*生成tail结点*/tail->tag=LIST; /*将标志域置为LIST*/tail->ptr.hp=p->tp; /*将tail的表头指针域指向广义表的表尾*/tail->tp=NULL; /*将tail的表尾指针域置为空*/return tail; /*返回指向广义表表尾结点的指针*/}//求广义表的长度操作int GListLength(GList L){int length=0; /*初始化化广义表的长度*/GLNodeList *p=L->ptr.hp;while(p) /*如果广义表非空,则将p指向表尾指针,统计表的长度*/{length++;p=p->tp;}return length; }//求广义表的深度操作int GListDepth(GList L){int max,depth;GLNode *p;if(L->tag==LIST&&L->ptr.hp==NULL) /*如果广义表非空,则返回1*/return 1;if(L->tag==ATOM) /*如果广义表是原子,则返回0*/return 0;p=L->ptr.hp;for(max=0;p;p=p->tp) /*逐层处理广义表*/{depth=GListDepth(p);if(max<depth)max=depth;}return max+1;}//广义表的复制操作。由广义表L复制得到广义表Tvoid CopyList(GList *T,GList L){if(!L) /*如果广义表为空,则T为空表*/*T=NULL;else{*T=(GList)malloc(sizeof(GLNodeList)); /*表L不空,为T建立一个表结点*/if(*T==NULL)exit(-1);(*T)->tag=L->tag;if(L->tag==ATOM) /*复制原子*/(*T)->ptr.atom=L->ptr.atom;elseCopyList(&((*T)->ptr.hp),L->ptr.hp);/*递归复制表头*/if(L->tp==NULL)(*T)->tp=L->tp;elseCopyList(&((*T)->tp),L->tp);/*递归复制表尾*/}}//将串Str分离成两个部分,HeadStr为第一个逗号之前的子串,Str为逗号后的子串void DistributeString(SeqString *Str,SeqString *HeadStr){int len,i,k;SeqString Ch,Ch1,Ch2,Ch3;len=StrLength(*Str);//len为Str的长度StrAssign(&Ch1,",");//将字符','、'('和')'分别赋给Ch1,Ch2和Ch3StrAssign(&Ch2,"("); StrAssign(&Ch3,")"); SubString(&Ch,*Str,1,1);//Ch保存Str的第一个字符for(i=1,k=0;i<=len&&StrCompare(Ch,Ch1)||k!=0;i++) /*搜索Str最外层的第一个括号*/{ SubString(&Ch,*Str,i,1);/*取出Str的第一个字符*/if(!StrCompare(Ch,Ch2))/*如果第一个字符是'(',则令k加1*/k++; else if(!StrCompare(Ch,Ch3))/*如果当前字符是')',则令k减去1*/k--; }if(i<=len)/*串Str中存在',',它是第i-1个字符*/{SubString(HeadStr,*Str,1,i-2);/*HeadStr保存串Str','前的字符*/SubString(Str,*Str,i,len-i+1);/*Str保存串Str','后的字符*/}else/*串Str中不存在','*/{StrCopy(HeadStr,*Str);/*将串Str的内容复制到串HeadStr*/StrClear(Str);/*清空串Str*/}}//采用头尾链表创建广义表void CreateList(GList *L,SeqString S){SeqString Sub,HeadSub,Empty;GList p,q;StrAssign(&Empty,"()"); if(!(*L=(GList)malloc(sizeof(GLNodeList))))/*为广义表生成一个结点*/exit(-1);if(!StrCompare(S,Empty))/*如果输入的串是空串则创建一个空的广义表*/{(*L)->tag=LIST; (*L)->ptr.hp=(*L)->tp=NULL;}else {if(StrLength(S)==1)/*广义表是原子,则将原子的值赋值给广义表结点*/{(*L)->tag=ATOM;(*L)->ptr.atom=S.str[0];(*L)->tp=NULL;}else/*如果是子表*/{(*L)->tag=LIST;(*L)->tp=NULL;SubString(&Sub,S,2,StrLength(S)-2);/*将S去除最外层的括号,然后赋值给Sub*/DistributeString(&Sub,&HeadSub);/*将Sub分离出表头和表尾分别赋值给HeadSub和Sub*/CreateList(&((*L)->ptr.hp),HeadSub);/*递归调用生成广义表*/p=(*L)->ptr.hp;while(!StrEmpty(Sub))/*如果表尾不空,则生成结点p,并将尾指针域指向p*/{DistributeString(&Sub,&HeadSub);CreateList(&(p->tp),HeadSub);p=p->tp;}}}}//输出广义表的元素void PrintGList(GList L){if(L->tag == LIST){printf("(");/*如果子表存在,先输出左括号 */if(L->ptr.hp == NULL)/*如果子表为空,则输出' '字符 */printf(" ");else/*递归输出表头*/PrintGList(L->ptr.hp);printf(")");/*在子表的最后输出右括号 */}else/*如果是原子,则输出结点的值*/printf("%c", L->ptr.atom);if(L->tp != NULL){printf(", ");/*输出逗号*/PrintGList(L->tp);/*递归输出表尾*/}}//------------------------void main(){GList L,T;SeqString S;int depth,length;StrAssign(&S,"(a,(),(a,(b,c)))");/*将字符串赋值给串S*/CreateList(&L,S);/*由串创建广义表L*/printf("输出广义表L中的元素:\n");PrintGList(L);/*输出广义表中的元素*/length=GListLength(L);/*求广义表的长度*/printf("\n广义表L的长度length=%2d\n",length);depth=GListDepth(L);/*求广义表的深度*/printf("广义表L的深度depth=%2d\n",depth);CopyList(&T,L);printf("由广义表L复制得到广义表T.\n广义表T的元素为:\n");PrintGList(T);length=GListLength(T);/*求广义表的长度*/printf("\n广义表T的长度length=%2d\n",length);depth=GListDepth(T);/*求广义表的深度*/printf("广义表T的深度depth=%2d\n",depth);system("pause");}

#pragma once#include<stdio.h>#include<stdlib.h>#define MaxLength 60typedef struct{char str[MaxLength];int length;}SeqString;//串的赋值操作void StrAssign(SeqString *S,char cstr[]){int i;for(i=0;cstr[i]!='\0';i++)S->str[i]=cstr[i];//将常量cstr中的字符赋值给串SS->length=i;}//判断串是否为空,串为空返回1,否则返回0int StrEmpty(SeqString S){if(S.length==0)return 1;elsereturn 0;}//求串的长度操作int StrLength(SeqString S){return S.length;}//串的复制操作void StrCopy(SeqString *T,SeqString S){int i;for(i=0;i<S.length;i++)//将串S的字符赋值给串TT->str[i]=S.str[i];T->length=S.length;//将串S的长度赋值给串T}//串的比较操作int StrCompare(SeqString S,SeqString T){//比较两个串中的字符int i;for(i=0;i<S.length&&i<T.length;i++){//比较两个串中的字符if(S.str[i]!=T.str[i])//如果出现字符不同,则返回两个字符的差值return (S.str[i]-T.str[i]);}return (S.length-T.length);//如果比较完毕,返回两个串的长度的差值}//串的插入操作。在S中第pos个位置插入T分为三种情况int StrInsert(SeqString *S,int pos,SeqString T){int i;if(pos<0||pos-1>S->length){//插入位置不正确,返回0printf("插入位置不正确");return 0;}if(S->length+T.length<=MaxLength){//第一种情况,插入子串后串长≤MaxLength,即子串T完整地插入到串S中for(i=S->length+T.length-1;i>=pos+T.length-1;i--)//在插入子串T前,将S中pos后的字符向后移动len个位置S->str[i]=S->str[i-T.length];for(i=0;i<T.length;i++)//将串插入到S中S->str[pos+i-1]=T.str[i];S->length=S->length+T.length;return 1;}else if(pos+T.length<=MaxLength){//第二种情况,子串可以完全插入到S中,但是S中的字符将会被截掉for(i=MaxLength-1;i>T.length+pos-i;i--)//将S中pos以后的字符整体移动到数组的最后S->str[i]=S->str[i-T.length];for(i=0;i<T.length;i++)//将T插入到S中S->str[i+pos-1]=T.str[i];S->length=MaxLength;return 0;}else{//第三种情况,子串T不能被完全插入到S中,T中将会有字符被舍弃for(i=0;i<MaxLength-pos;i++)//将T直接插入到S中,插入之前不需要移动S中的字符S->str[i+pos-1]=T.str[i];S->length=MaxLength;return 0;}}//在串S中删除pos开始的len个字符int StrDelete(SeqString *S,int pos,int len){int i;if(pos<0||len<0||pos+len-1>S->length){printf("删除位置不正确,参数len不合法");return 0;}else{for(i=pos+len;i<=S->length-1;i++)S->str[i-len]=S->str[i];S->length=S->length-len;return 1;}}//串的连接操作int StrCat(SeqString *T,SeqString S){int i,flag;if(T->length+S.length<=MaxLength){for(i=T->length;i<T->length+S.length;i++)T->str[i]=S.str[i-T->length];T->length=T->length+S.length;flag=1;}else if(T->length<MaxLength){for(i=T->length;i<MaxLength;i++)T->str[i]=S.str[i-T->length];T->length=MaxLength;flag=0;}return flag;}//截取子串操作int SubString(SeqString *Sub,SeqString S,int pos,int len){int i;if(pos<0||len<0||pos+len-1>S.length){printf("参数pos和len不合法");return 0;}else{for(i=0;i<len;i++)Sub->str[i]=S.str[i+pos-1];Sub->length=len;return 1;}}//串的定位操作int StrIndex(SeqString S,int pos,SeqString T){int i,j;if(StrEmpty(T))return 0;i=pos;j=0;while(i<S.length&&j<T.length){if(S.str[i]==T.str[j]){i++;j++;}else{i=i-j+1;j=0;}}if(j>=T.length)return i-j+1;else return 0;}//串的替换操作int StrReplace(SeqString *S,SeqString T,SeqString V){//将S中所有的T替换为Vint i;int flag;if(StrEmpty(T))return 0;i=0;do{i=StrIndex(*S,i,T);//找到T在S中的位置if(i){StrDelete(S,i,StrLength(T));//删除找到的Tflag=StrInsert(S,i,V);//在i位置插入Vif(!flag)return 0;i+=StrLength(V);}}while(i);return 1;}//串的清空操作void StrClear(SeqString *S){S->length=0;}//===========void StrPrint(SeqString S){int i;for(i=0;i<S.length;i++){printf("%c",S.str[i]);}printf("\n");}

1 0