线性表拓展之广义表

前言:我们知道可以定义一个链表来表示一元多项式,数据结构如下:

/*typedef帮原有类型重命名,在此是帮struct node这个结构体重命名为LNode*/ 
typedef struct node
{
	/*ratio表示多项式系数,index表示指数*/ 
	int ratio,index;
	struct node *next;
}LNode;

但对于二元多项式,就不能使用以上的结构体来表示了,我们用广义表来表示二元多项式。

正文:

1,基础概念

广义表是线性表的推广,对于线性表而言,只含有一个链表,里面的元素同属于一个链表。但广义表中有些元素却同属于其它广义表。线性表中每个元素必须具有相同的数据结构,广义表中的数据元素可以具有不同的数据结构。

广义表一般表示为:GL=(d1,d2,d3.......,dn),其中,GL为广义表的名称,n是广义表的长度,di可以是单个元素也可以是广义表,若为广义表,则称为GL的子表,若为单个元素,则称为广义表的原子。

递归表:F是一个长度为2的广义表,第一个元素是原子,第二个元素是其自身。将其展开将得到一个无限表。3

注意:

(1)通常情况下,广义表用圆括号圈起来,用逗号分隔其中的元素

(2)习惯上,用大写字母表示广义表的名称,用小写字母表示广义表的原子。

(3)若广义表非空,则d1表示广义表的表头,其余元素表示表尾。对于一个非空的广义表,其表头有可能是原子,也有可能是子表,但一个广义表的表尾必定为广义表。

(4)一个广义表展开后所含括号的层数称为广义表的深度

广义表的数据结构:

typedef struct node
{
	/*Tag为标志域,为1,说明结点是广义表,为0,说明是单元素*/ 
	int Tag;
	union{
		ElementType Data;/*ElementType为元素类型,实际用时可以改为任意类型*/ 
		struct node *SubList;
	}URegion;
	struct node *next;
}GNode,*GList;

广义表的创建:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MAX 50
/*数据结构*/ 
typedef struct node
{
	int  tag;
	char atom;
	struct node *hp,*tp; 
}GNode,*GList;
GList creat(char str[]);/*构造广义表,并赋值*/
/*找出结点对应的子广义表所含的字符串*/ 
void Getsubs(char str[],char hstr[]);
int main(void)
{
	FILE *f;
	char str[MAX];
	GList G;
	G=NULL;
	f=fopen("D:\\num.txt","r");
	if(f==NULL)
	{
		printf("failed to open the file\n");exit(0);
	}
	fgets(str,50,f);
	G=creat(str);
	return 0;
}
void Getsubs(char str[],char hstr[])
{
	/*k表示单的左括号的数量*/ 
	int i=0,j=0,k=0;
	char s[MAX];
	while(str[i]&&(str[i]!=','||k))
	{
		if(str[i]=='(')
		k++;
		else if(str[i]==')')
		k--;
		if(str[i]!=','||str[i]==','&&k)
		{
			hstr[j]=str[i];
			i++;j++;
		}
	}
	hstr[j]='\0';
	if(str[i]==',')
	i++;
	k=0;
	while(str[i]!='\0')
	{
		s[k]=str[i];
		k++;i++;
	}
	s[k]='\0';
	/*这时的s为去除了最外层括号和第一个逗号的字符串*/ 
	strcpy(str,s);
} 
GList creat(char str[])
{
	int len,i;
	GList G,p,r,q;
	/*subs数组放str数组去除最外面一对圆括号后的数组元素,hstr放子广义表的元素*/ 
	char subs[MAX],hstr[MAX];
	/*求出Str的长度*/ 
	len=strlen(str);
	if(len==0||!strcmp(str,"()"))/*广义表为空*/ 
	G=NULL;
	else if(len==1)/*广义表只有一个元素*/ 
	{
		G=(GList)malloc(sizeof(GNode));
		if(!G)
		{
			printf("申请空间失败!");exit(0);
		}
		G->tag=0;G->atom=*str;G->tp=NULL;
	}
	else/*有子广义表的广义表*/ 
	{
		G=(GList)malloc(sizeof(GNode));
		if(!G)
		{
			printf("申请空间失败!");exit(0);
		}
		G->tag=1;
		p=G;
		/*将str字符串除了最外面一对圆括号外复制给subs*/ 
		strncpy(subs,&str[1],len-1);
		subs[len-2]='\0';
		while(len>0)
		{
			Getsubs(subs,hstr);
			/*递归思想,找到深度最大的字符串,然后依次建立广义表的结点*/ 
			r=creat(hstr);
			p->hp=r;
			q=p;len=(strlen(subs));
			if(len>0)
			{
				p=(GList)malloc(sizeof(GNode));
				if(p==NULL)
				{
					printf("申请空间失败!");exit(0);
				}
				p->tag=1;
				q->tp=p;
			}
		}
		q->tp=p;
	}
	return G;
}


广义表的一个具体体现就是多重链表,链表中的结点可能同属于多个链,如下图

2,广义表表示二元多项式

可以将二元多项式看为一元多项式,例如:P(x,y)=(9y^2+4)x^12+(15y^3-y)x^8+3x^2看为ax^12+bx^8+cx^2

数据结构如下

/*typedef帮原有类型重命名,在此是帮struct node这个结构体重命名为LNode*/ 
typedef struct node
{
	/*ratio表示多项式系数,index表示指数*/ 
	int ratio,index;
	struct node *next,*down;
}LNode;

图片




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值