码迷,mamicode.com
首页 > 其他好文 > 详细

33. 蛤蟆的数据结构笔记之三十三广义表实现二

时间:2015-07-14 22:44:17      阅读:144      评论:0      收藏:0      [点我收藏+]

标签:

33. 蛤蟆的数据结构笔记之三十三广义表实现二

本篇名言: 希望是附丽于存在的,有存在,便有希望,有希望,便是光明。--鲁迅

我们继续来看下广义表的其他代码实现。代码均来自网络,解释来自蛤蟆,均亲测可行。

欢迎转载,转载请标明出处:


1.  广义表实现二

1.1         main

创建两个链表的指针head和L。

输入一个字符串,调用GLCreate函数创建广义表。显示,获取头表,尾表,输出长度,深度,原子个数,复制列表,Merge列表,遍历,比较广义表操作。

如下图1:

技术分享

代码如下:

int main()

{

         chars[MAXSIZE],a[MAXSIZE];

         GListhead;

         GListL;

         printf("pleaseinput a string:");

         scanf("%s",s);

         head =GLCreate(s);

         DisplayList(head);

         printf("\n");

         printf("TheHead is:");

         DisplayList(GetHead(head));

         printf("\n");

         printf("TheTail is: ");

         DisplayList(GetTail(head));

         printf("\n");

         printf("TheLength is %d\n",Length(head));

         printf("TheDepth is %d\n",Depth(head));

         printf("TheAtom number is %d\n",CountAtom(head));

         printf("Copythe List:\n");

         CopyList(&L,head);

         DisplayList(L);

         printf("\n");

         printf("Mergethe List\n");

         Merge(&L,head);

         DisplayList(L);

         printf("\n");

         printf("PreOrder:");

         PreOrder(head);

         printf("\n");

         printf("inputa string:");

         scanf("%s",a);

         L =GLCreate(a);

         DisplayList(L);

         printf("Eqaul ");

         DisplayList(head);

         printf(":");

         if(Equal(L,head)) printf("yes!\n");

         elseprintf("no!\n");

         return0;

}

1.2         定义结构体

定义结构体,同实现一

typedef struct GLNode

{

         ElemTagtag;

         union

         {

                   AtomType  atom;

                   struct GLNode*hp;

         }atom_hp;

         struct GLNode*tp;

}GLNode,*GList;

 

 

1.3         GLCreate

根据输入的字符串,建立广义表,成功则返回建立的广义表的表头,否则,返回NULL。

具体过程是这个样子的,先创建变量p,q,r,head。 然后先获取输入字符串的长度,对比字符串是否为“()”,以及字符串长度是否为0,如果满足其中之一,直接设置head=NULL,并返回head。

如果字符串长度为1,那么创建一个原子节点,并返回。

如果其他情况,创建一个head节点,设置tag为1,复制给p。然后将除去()之外的字符串赋值给substr临时变量。

 然后取出substr的表头,让p指向这个表头,然后赋值给q. 接着计算剩余字符串的长度,如果大于0,则创建一个节点p,让q指向p. 根据len 是否大于零,继续取出表头进行循环。最后返回head.

PS:函数更多的是功能的实现,所以输入需要当前使用的朋友自己把关。原子节点也是一个字符。

 

 

 

1.4         Disastr

分离出广义表中表头部分,分离后剩下的字符串,不包括逗号

具体描述:

输入两个字符串的指针s,hstr。如果*s不为NULL且不是’,’ 或者K不为0,则进入第一个循环,判断是否*s为’(‘,如果是则K++. 如果是‘)’,则K- -。(K是括号计数器)

如果*s 为‘,’并且k不为0 或者 *s不为’,’ ,将*s赋值给hstr.

然后将剩余的留给rstr并通过s指针返回。

void Disastr(char *s,char *hstr)

{

         inti,j,k,r;

         charrstr[MAXSIZE];

 

         i=j=k=0;

         while(s[i]&& (s[i] != ‘,‘|| k))

         {

                   if (s[i]== ‘(‘) {  k++ ; }        // k 作为括号计数器       

                   else if (s[i]== ‘)‘) {k--;}

                   if (s[i]!= ‘,‘ || s[i]== ‘,‘ && k)

                   {

                            hstr[j]= s[i];

                            i++;

                            j++;

                   }

         }

         hstr[j]= ‘/0‘;

         if (s[i]== ‘,‘) {i++;}

         r=0;

         while(s[i])                 // 处理剩余的表尾部分

         {

                   rstr[r]= s[i];

                   r++;

                   i++;

         }

         rstr[r]= ‘/0‘;

         strcpy(s,rstr);

}

1.5         GetHead

取出广义表的表头部分,成功则返回广义表的表头,否则,返回空或退出。

具体描述:

如果为空,则返回NULL,如果tag为0,则退出,否则返回指针。

1.6         GetTail

取出广义表的表尾部分,成功返回广义表的表尾部分,否则,返回空或者退出。

 

1.7         DisplayList

打印广义表。

1.8         Length

求出广义表的长度,返回广义表的长度。

 

1.9         Depth

求得广义表的深度,求广义表的深度。

1.10    CountAtom

统计原子结点的个数。

1.11    CopyList

完成广义表的复制,将res复制到dest中,成功返回1,否则,返回0

1.12    Merge

合并广义表,如果p为空,则申请空间,将q复制到p中。

例如:((a,b),c) 和(a,b)合并之后为:((a,b),c,a,b)

算法描述:先找到第一个广义表的最后一个结点,将其链到第二个广义表的首元素即可

1.13    PreOrder

类似二叉树的先序遍历遍历广义表L

例如(a,(b,(c),d))结果为:a,b,c,d

L若为原子结点,显示该数据,递归调用遍历后续元素。

L是子表结点,递归调用遍历该子表,遍历后续元素。

1.14    Equal

判断两个广义表是否相等,相等,返回1,否则,返回0

相等的定义:两个广义表具有相同的存储结构,对应的原子结点的数据域也相等

1.15   源码

#include <stdio.h>

#include <string.h>

#include <stdlib.h>

#define AtomType char

#define MAXSIZE  1024

#define ElemTag int

#define OK       1

#define ERROR    0

 

typedef struct GLNode

{

         ElemTagtag;

         union

         {

                   AtomType  atom;

                   struct GLNode*hp;

         }atom_hp;

         struct GLNode*tp;

}GLNode,*GList;

 

//功能:分离出广义表中表头部分

//返回:分离后剩下的字符串,不包括逗号

void Disastr(char *s,char *hstr)

{

         inti,j,k,r;

         charrstr[MAXSIZE];

 

         i=j=k=0;

         while(s[i]&& (s[i] != ‘,‘|| k))

         {

                   if (s[i]== ‘(‘) {  k++ ; }        // k 作为括号计数器       

                   else if (s[i]== ‘)‘) {k--;}

                   if (s[i]!= ‘,‘ || s[i]== ‘,‘ && k)

                   {

                            hstr[j]= s[i];

                            i++;

                            j++;

                   }

         }

         hstr[j]= ‘\0‘;

         if (s[i]== ‘,‘) {i++;}

         r=0;

         while(s[i])                 // 处理剩余的表尾部分

         {

                   rstr[r]= s[i];

                   r++;

                   i++;

         }

         rstr[r]= ‘\0‘;

         strcpy(s,rstr);

}

//功能:根据输入的字符串,建立广义表

//返回:成功则返回建立的广义表的表头,否则,返回NULL

GLNode * GLCreate(char *s)

{

         GLNode*p,*q,*r,*head;

         charsubstr[MAXSIZE],hstr[MAXSIZE];//rstr[MAXSIZE];

         intlen;

         len =strlen(s);

         if (!strcmp(s,"()")|| !len)  { head = NULL;}     // (1) 空表情况

         else if(len == 1)                                     // (2) 原子情况

         {

                   head= (GLNode *)malloc(sizeof(GLNode));       // 建立一个新结点

                   if(!head)  return NULL;    

                   head->tag= 0;                                 //构造原子结点

                   head->atom_hp.atom= *s;

                   head->tp= NULL;

         }

         else                                               // (3) 子表情况

         {

                   head= (GLNode *)malloc(sizeof(GLNode));

                   if(!head) return NULL;

                   head->tag= 1;

                   p= head;

                   s++;

                   strncpy(substr,s,len-2);                         //剥去外层的()

                   substr[len-2]= ‘\0‘;

                   do

                   {

                            Disastr(substr,hstr);                        //分离出表头

                            r= GLCreate(hstr);

                            p->atom_hp.hp= r;                           //尾插法建表

                            q=p;

                            len= strlen(substr);

                            if(len > 0)

                            {

                                     p= (GLNode*)malloc(sizeof(GLNode));

                                     if(!p) return NULL;

                                     p->tag= 1;

                                     q->tp=p;

                            }

                   }while(len > 0);

                   q->tp=NULL;

         }

         returnhead;

}

void DisplayList(GList head)

{

         GLNode*p,*q;

 

         if(!headreturn;

         if (head->tag==0)

         {

                   printf("%c",head->atom_hp.atom);

                   return;

         }

         printf("(");

         if (head)

         {

                   do

                   {

                            p= head->atom_hp.hp;

                            q= head->tp;

                            while(q && p && p->tag == 0)                //  同一层的原子结点

                            {

                                     printf("%c,",p->atom_hp.atom);

                                     p= q->atom_hp.hp;

                                     q= q->tp;

                            }

                            if(p && !p->tag)                           //最后一个原子结点

                            {

                                     printf("%c",p->atom_hp.atom);

                                     break;

                            }

                            else                                        //子表情况

                            {

                                     if(!p) printf("()");

                                     elseDisplayList(p);

                                     if(q)  printf(",");

                                     head =q;

                            }

                   }while (head);

                   printf(")");

         }

}

//功能:取出广义表的表头部分

//返回:成功则返回广义表的表头,否则,返回空或退出

GList GetHead(GList L)

{

         if(!Lreturn (NULL);                    // 空表无表头

         if (L->tag== 0)  exit(0);                 // 原子结点不是表

         else return (L->atom_hp.hp);

}

//功能:取出广义表的表尾部分

//返回:成功返回广义表的表尾部分,否则,返回空或者退出

GList GetTail(GList L)

{

         if(!L) return (NULL);

         if (L->tag== 0) exit(0);

         else return (L->tp);

}

//功能:求出广义表的长度

//返回值:广义表的长度

int Length(GList L)

{

         intk=0;

         GLNode*s;

         if(!L) return0;                    //空表的长度为零

         if (L->tag== 0) exit(0);            //原子不是表

         s=L;

         while(s)                             //统计表的最上层的长度

         {

                   k++;

                   s=s->tp;

         }

         returnk;

}

 

//功能:求得广义表的深度

//输入:需求深度的广义表的指针

int Depth(GList L)

{

         intd,max;

         GLNode*s;

         if(!Lreturn (1);            // 空表的深度为 1

         if (L->tag==0)  return 0;       // 原子的深度为 0

         s=L;

         max=0;

         while(s)                        //递归求每个子表深度的最大值

         {

                   d= Depth(s->atom_hp.hp);

                   if(d > max) max = d;

                   s= s->tp;

         }

         return(max+1);                  //表的深度为子表深度加一

}

 

//功能:统计原子结点的个数

//输入:需统计的广义表指针

int CountAtom(GList L)

{

         intn1,n2;

         if(!L) return0;                   //空表无原子结点

         if (L->tag==0)return1;            // 原子结点

         n1 =CountAtom(L->atom_hp.hp);     

         n2 =CountAtom(L->tp);

         return(n1+n2);

}

//功能:完成广义表的复制,res复制到dest

//返回:成功返回1,否则,返回0

bool CopyList(GList *dest,GList res)

{

         if(!res) {*dest =NULL;return (OK);}

         *dest =(GLNode*)malloc(sizeof(GLNode));

         if(!*destreturn (ERROR);

         (*dest)->tag= res->tag;

         if (res->tag==0)  (*dest)->atom_hp.atom= res->atom_hp.atom;

         else

         {

                   CopyList(&(*dest)->atom_hp.hp,res->atom_hp.hp);

                   CopyList(&(*dest)->tp,res->tp);

         }

         return (OK);

}

//功能:合并广义表,如果p为空,则申请空间,将q复制到p

//例如:((a,b),c)(a,b)合并之后为:((a,b),c,a,b)

//算法描述:先找到第一个广义表的最后一个结点,将其链到第二个广义表的首元素即可

void Merge(GList *p,GLNode *q)

{

         GLNode*r;

         if(!q) return;       //  如果复制的是个空表,返回

         if(!p)               // p为空,申请空间

         {

                   *p =(GLNode*)malloc(sizeof(GLNode));

                   if(!(*p)) return ;

                   (*p)->tag= 1;

         }

         else

         {

                   if((*p)->tag)        

                   {

                            r=*p;

                            while(r->tp)r=r->tp;             //找到最后一个子表的表尾指针

                            if (q->tag)r->tp = q;        // 修改表尾指针

                   }

         }

}

//功能:类似二叉树的先序遍历遍历广义表L

//eg:例如(a,(b,(c),d))结果为:a,b,c,d

//算法描述:

//L若为原子结点,显示该数据,递归调用遍历后续元素,也即:write(L->atom_hp.atom);PreOrder(L->tp);

//L是子表结点,递归调用遍历该子表,遍历后续元素,也即:PreOrder(L->atom_hp.tp);PreOrder(L->tp);

void PreOrder(GList L)

{

         if (L)

         {

                   if (L->tag==0)printf("%c ",L->atom_hp.atom);   // 打印原子结点

                   else  PreOrder(L->atom_hp.hp);                  // 往下遍历,类似二叉树中的左子树

                   if (L->tp)PreOrder(L->tp);                     // 往右遍历,类似二叉树中的右子树

         }

}

// 判断两个广义表是否相等,相等,返回1,否则,返回0

// 相等的定义:两个广义表具有相同的存储结构,对应的原子结点的数据域也相等

//算法描述:

// 形式:条件

//Equal(p,q) = Equal(p->tp,q->tp) ; p->tag= 0 && q->tag = 0 && p->atom_hp.atom = q->atom_hp.atom

//Equal(p,q) =Equal(p->atom_hp.hp,q->atom_hp.hp) && Equal(p->tp,q->tp) ;p->tag = 1 && q->tag = 1

//Equal(p,q) = false     ; p->tag = 0 && q->tag = 0p->atom_hp.atom != q->atom_hp.atom 或者p->tag *p->tag + q->tag*q->tag =1

//Equal(p,q) = false      ; p q 其中之一为NULL

bool Equal(GList p,GList q)

{

         boolflags = true;

         if(!p && q)flags = false;

         if (p&& !q) flags = false;

         if (p&& q)

         {

                   if (p->tag== 0 && q->tag == 0 )

                   {

                            if (p->atom_hp.atom!= q->atom_hp.atom)

                                     flags= false;

                   }

                   else if (p->tag== 1 && q->tag == 1)

                   {

                            flags= Equal(p->atom_hp.hp,q->atom_hp.hp);

                   }

                   elseflags = false;

                   if(flags) flags = Equal(p->tp,q->tp);

         }

         returnflags;

}

int main()

{

         chars[MAXSIZE],a[MAXSIZE];

         GListhead;

         GListL;

         printf("pleaseinput a string:");

         scanf("%s",s);

         head =GLCreate(s);

         DisplayList(head);

         printf("\n");

         printf("TheHead is:");

         DisplayList(GetHead(head));

         printf("\n");

         printf("TheTail is: ");

         DisplayList(GetTail(head));

         printf("\n");

         printf("TheLength is %d\n",Length(head));

         printf("TheDepth is %d\n",Depth(head));

         printf("TheAtom number is %d\n",CountAtom(head));

         printf("Copythe List:\n");

         CopyList(&L,head);

         DisplayList(L);

         printf("\n");

         printf("Mergethe List\n");

         Merge(&L,head);

         DisplayList(L);

         printf("\n");

         printf("PreOrder:");

         PreOrder(head);

         printf("\n");

         printf("inputa string:");

         scanf("%s",a);

         L =GLCreate(a);

         DisplayList(L);

         printf("Eqaul ");

         DisplayList(head);

         printf(":");

         if(Equal(L,head)) printf("yes!\n");

         elseprintf("no!\n");

         return0;

}

 

版权声明:本文为博主原创文章,未经博主允许不得转载。

33. 蛤蟆的数据结构笔记之三十三广义表实现二

标签:

原文地址:http://blog.csdn.net/notbaron/article/details/46882881

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!