前言:我们知道可以定义一个链表来表示一元多项式,数据结构如下:
/*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;
图片