数据结构(C语言)例子连载(4)====广义表的实现

实现广义表,具体没有做习题,感觉有些累了。呵呵。不知再往下看,脑细胞是否经得起折腾。先把源文件贴 上来。
// glist.h
// ----------------------- 广义表 ---------------------------------------
typedef  enum {ATOM, LIST}  ElemTag;     // ATOM==0:原子,LIST==1:子表 
typedef  int  AtomType;                 // 原子的数据类型

typedef 
struct  GLNode {
    ElemTag tag;                    
//公共部分,区分原子节点和表节点
    union{                            //原子节点和表节点的联合部分
        AtomType atom;                //原子节点的值
        struct GLNode *hp;            //表节点的表头指针
    }
;
    
struct GLNode *tp;                //相当于线形链表的next,指向下一个元素
}
* GList;

// ----------------- 基本操作的算法实现 -------------------------------
Status Sever(HString  & str, HString  & hstr) {
    
//将非空串str分割成两部分:hstr为第一个','之前的自串,str为之后的子串
    int n = StrLength(str), i=1, k=0;            //k记尚未配对的左括号个数
    HString ch;StrInit(ch);StrAssign(ch,"a");
    
for(i=1, k=0; i<=n&&ch.ch[0]!=','||k!=0;i++){    //搜索最外层的第一个','
        SubString(ch,str,i,1);
        
if(ch.ch[0]=='('++k;
        
else if(ch.ch[0]==')')--k;
    }

    
if(i<=n){ SubString(hstr,str,1,i-2); SubString(str,str,i,n-i+1); }
    
else{StrCopy(hstr,str); ClearString(str);}
    
return OK;
}


Status CreateGList(GList 
& L, HString S) {
    
//采用头尾链接存储结构,由广义表的书写形式串S创建广义表L
    HString emp; StrInit(emp); StrAssign(emp,"()");
    GList p,q;
    
if!StrCompare(S,emp) ) L=NULL;    //创建空表
    else{
        
if(!(L=(GList)malloc(sizeof(GLNode)))) exit(OVERFLOW);  //创建节点
        if(StrLength(S)==1{L->tag = ATOM; L->atom = *(S.ch);}    //创建原子节点
        else{
            L
->tag = LIST; p=L;
            HString sub,hsub; StrInit(sub); StrInit(hsub);
            SubString(sub,S,
2,StrLength(S)-2);                    //脱外层扩号
            do{
                Sever(sub,hsub);
                CreateGList(p
->hp,hsub); q=p;
                
if(!StrEmpty(sub)){
                    
if(!(p=(GLNode *) malloc(sizeof(GLNode))))    
                        exit(OVERFLOW);
                    p
->tag = LIST; q->tp = p;
                }

            }
while(!StrEmpty(sub));
            q
->tp = NULL;
        }

    }

    
return OK;
}


Status CopyGList(GList 
& T, GList L) {
    
//L复制给T
    if(!L) T=NULL;
    
else{
        
if(!(T=(GList)malloc(sizeof(GLNode)))) exit(OVERFLOW);
        T
->tag = L->tag;
        
if(L->tag ==ATOM ) T->atom = L->atom;
        
else{
            CopyGList(T
->hp, L->hp);
            CopyGList(T
->tp, L->tp);
        }

    }

    
return OK;
}


int  GListDepth(GList L) {
    
//求广义表的深度
    if(!L) return 1;
    
if(L->tag==ATOM) return 0;
    
int max;
    GList pp;
    
for(max=0,pp=L;pp;pp=pp->tp){
        
int dep = GListDepth(pp->hp);
        
if(dep>max) max= dep;
    }

    
return max+1;
}


Status PrintGList(GList L)
{
    
//显示广义表
    GList p = L;
    
if(!L)    {printf("()"); return OK;    }
    
if(L->tag== ATOM)  printf("%c",L->atom);
    
else{            
        printf(
"(");
        
while(p!=NULL){
            PrintGList(p
->hp);    
            p
=p->tp;                    
            
if(p)  {  printf(","); }            
        }
    
        printf(
")");    
    }

    
return OK;
}

2.

//hstring.h
//----------------- 串的堆分配存储表示  ---------------------------
typedef struct{
    char *ch;    //若是非空串,则按串长分配存储区,否则ch为NULL
    int length;    //串长度
}HString;

//----------------- 栈的基本操作的算法实现 --------------------------------
Status StrInit(HString &T){
    //初始化串
    T.ch=NULL; T.length=0;
    return OK;
}

Status StrAssign(HString &T, char *chars){
    //生成一个其值等于串常量chars的串T
    //if(T.ch) free(T.ch);                //释放原有的串空间
    int len;  char *c;
    for(len=0, c=chars;*c;++len,++c);  //求chars的长度i;
    if(!len) {T.ch=NULL; T.length=0;}
    else{
        if( !(T.ch = (char *) malloc(len*sizeof(char) ) ))
            exit(OVERFLOW);
        for(int i=0;i<len;i++)  T.ch[i] = chars[i];
        T.ch[i]='/0';            //结尾加上/0
        T.length = len;
    }

    return OK;
}

int StrLength(HString s){
    //返回串长度
    return s.length;
}

void StrPrint(HString s){
    //打印串
    for(int i=0;i<s.length;i++)
        printf("%c",s.ch[i]);
    printf("/n");
}

int Index(HString s,HString t, int pos){
    //返回子串t在主串s中第pos个字符之后的位置。如不存在,则返回0    
    int i=pos,j=1;
    while(i<=s.length && j<=t.length){
        if(s.ch[i-1]==t.ch[j-1])  i++,j++;
        else            i=i-j+2,j=1;
    }
    if(j>t.length) return i-t.length;
    else return 0;
}

int Next(HString s,int j){
    //KMP模式匹配的next函数
    if(j==1) return 0;

    for(int k=j-1;k>1;k--){
        for(int i=1;i<k;i++){
            if(s.ch[i-1] != s.ch[j-k+i-1])
                break;
        }
        if(i==k)  break;
    }
    return k;
}

int Index_KMP(HString s,HString t, int pos){
    //KMP算法
    int i=pos,j=1;
    while(i<=s.length && j<=t.length){
        if(j==0 || s.ch[i-1]==t.ch[j-1])   i++,j++;
        else    j=Next(t,j);
    }
    if(j>t.length) return i-t.length;
    else  return 0;
}

Status SubString(HString &sub, HString s, int pos, int len){
    //用sub返回串S的第pos个字符起长度为len的子串
    if(pos<1 || pos>s.length || len<0  )
        return ERROR;
    if( len>s.length-pos+1 ) len=s.length-pos+1;    //如果所取长度超过实际长度,输出实际长度
//    if(sub.ch) free(sub.ch);
    if(!len){ sub.ch=NULL; sub.length=0; }
    else{
        if( !(sub.ch = (char *) malloc(len*sizeof(char) ) ))
            exit(OVERFLOW);
        for(int i=0;i<len;i++)  sub.ch[i] = s.ch[pos+i-1];
        sub.ch[i]='/0';            //结尾加上/0
        sub.length = len;
    }
    return OK;
}

Status ClearString(HString &s){
    //清空s
    if(s.ch) {
    //    realloc(s.ch,0);
        s.ch=NULL;
    }
    s.length =0;
    return OK;
}

int StrCompare(HString s,HString t){
    //比较s,t
    for(int i=0;i<s.length&& i<t.length;i++)
        if(s.ch[i]!=t.ch[i]) return s.ch[i]-t.ch[i];
    return s.length - t.length;
}

Status Concat(HString &t, HString s1, HString s2){
    //用t返回由s1和s2联接而成的新串
    //if(t.ch) free(t.ch);
    if(!(t.ch=(char *)malloc((s1.length+s2.length)*sizeof(char))))
        exit(OVERFLOW);
    for(int i=0;i<s1.length;i++)  t.ch[i]=s1.ch[i];
    for(i=0;i<s2.length;i++) t.ch[i+s1.length]=s2.ch[i];        
    t.ch[s1.length+s2.length]='/0';
    t.length = s1.length+s2.length;
    return OK;
}

Status StrCopy(HString &t,HString s){
    if(!(t.ch=(char *)malloc( (s.length)*sizeof(char))))
        exit(OVERFLOW);
    for(int i=0;i<s.length;i++)  t.ch[i]=s.ch[i];
    t.ch[s.length] = '/0';
    t.length = s.length;
    return OK;
}

Status StrEmpty(HString s){
    return s.length==0;
    return OK;
}

【后记】又出同样问题了,help!! 呵呵
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
广义表是一种常用的数据结构,它可以表示多层次的嵌套结构。在C语言中,可以使用链表来实现广义表。 以下是一个简单的广义表C语言代码实现: ```c #include <stdio.h> #include <stdlib.h> // 结点的数据类型定义 typedef struct Node { char data; // 数据域,存储广义表的元素 struct Node* next; // 指针域,指向下一个结点 struct Node* sublist; // 子表指针,指向子表的头结点 } Node; // 创建结点 Node* createNode(char data) { Node* newNode = (Node*)malloc(sizeof(Node)); newNode->data = data; newNode->next = NULL; newNode->sublist = NULL; return newNode; } // 插入结点到广义表中 void insert(Node** head, char data) { if (*head == NULL) { *head = createNode(data); return; } Node* current = *head; while (current->next != NULL) { current = current->next; } current->next = createNode(data); } // 插入子表到广义表中 void insertSublist(Node** head, Node* sublist) { if (*head == NULL) { *head = sublist; return; } Node* current = *head; while (current->next != NULL) { current = current->next; } current->next = sublist; } // 打印广义表 void printList(Node* head) { if (head == NULL) { printf("()"); return; } printf("("); Node* current = head; while (current != NULL) { if (current->sublist == NULL) { printf("%c", current->data); } else { printList(current->sublist); } if (current->next != NULL) { printf(", "); } current = current->next; } printf(")"); } // 释放广义表的内存 void freeList(Node** head) { Node* current = *head; while (current != NULL) { Node* temp = current; current = current->next; if (temp->sublist != NULL) { freeList(&temp->sublist); } free(temp); } *head = NULL; } int main() { Node* list = NULL; // 插入元素到广义表中 insert(&list, 'A'); insert(&list, 'B'); insert(&list, 'C'); // 创建子表并插入到广义表中 Node* sublist = createNode('D'); insert(&sublist->sublist, 'E'); insert(&sublist->sublist, 'F'); insertSublist(&list, sublist); // 打印广义表 printList(list); // 释放广义表的内存 freeList(&list); return 0; } ``` 这段代码实现了一个简单的广义表,可以通过调用`insert`和`insertSublist`函数插入元素和子表,并通过`printList`函数打印整个广义表。记得在程序结束时,调用`freeList`函数释放广义表的内存。 注意:这只是一个简单的实现示例,实际应用中可能需要根据具体需求进行修改和扩展。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值