数据结构28:广义表及M元多项式
广义表,又称为列表。记作:
广义表可以看作是线性表的推广。两者区别是:线性表中的数据元素只能表示单个数据元素;广义表中的单个数据元素 ai ,既可以是单个元素,也可以是广义表。
原子和子表
在广义表中,单个元素被称为 “原子”;包含的广义表被称为 “子表”。
例如:
- A = () :A 表示一个广义表,只不过表是空的,广义表 A 的长度为 0。
- B = (e) :广义表 B 中只有一个原子 e ,长度为 1。
- C = (a,(b,c,d)) :广义表 C 中有两个元素,原子 a 和子表 (b,c,d) ,广义表C的长度为 2。
- D = (A,B,C) :广义表 D 中有三个元素:子表 A、B、C,长度为 3 ,这种表示方式等同于: D = ((),(e),(b,c,d)) 。
- E = (a,E) :广义表 E 中有两个元素,原子 a 和它本身,长度为 2 。这是一个递归的表,等同于:E = (a,(a,(a,…)))。
表头和表尾
当广义表不为空时,称表中的第一个元素为表的 “表头” ;剩余所有元素组成的表为 “表尾” 。
例如:上边例子中的 D = (A,B,C) ,子表 A 为广义表 D 的表头;而 (B,C) 组成的表为 D 的表尾。
非空广义表是由表头和表尾构成,反过来说也对:给定一个表头和表尾,可以唯一确定一个广义表。
广义表中结点结构
由于广义表中的数据元素类型分为原子和子表,难以使用顺序存储结构表示,所以通常采用链式存储结构。
根据原子和子表的不同,链式存储中的结点需要用两种不同的结构表示。对于原子来说,需要由两部分组成:标志位 + 值域(如图1(A));子表需要由三部分组成:标志位 + 指向表头的指针域 + 指向表尾的指针域(如图1(B))。
图1 广义表的链表结点结构
代码表示:
typedef struct GLNode
{
int tag; //标志域
union
{
char atom; //原子结点的值域
struct
{
struct GLNode *hp, *tp;
}ptr; //子表结点的指针域,hp指向表头;tp指向表尾
};
}*Glist;
例如,使用图1的链表结构表示广义表 C = (a,(b,c,d)),效果图为:
图2 广义表C的结构示意图
实现代码为:
Glist creatGlist(Glist C)
{
// 广义表C
C = (Glist)malloc(sizeof(Glist));
C->tag = ;
// 表头原子‘a’
C->ptr.hp = (Glist)malloc(sizeof(Glist));
C->ptr.hp->tag = ;
C->ptr.hp->atom = 'a';
// 表尾子表(b,c,d),是一个整体
C->ptr.tp = (Glist)malloc(sizeof(Glist));
C->ptr.tp->tag = ;
C->ptr.tp->ptr.hp = (Glist)malloc(sizeof(Glist));
C->ptr.tp->ptr.tp = NULL;
// 开始存放下一个数据元素(b,c,d), 表头为‘b’,表尾为(c,d)
C->ptr.tp->ptr.hp->tag = ;
C->ptr.tp->ptr.hp->ptr.hp = (Glist)malloc(sizeof(Glist));
C->ptr.tp->ptr.hp->ptr.hp->tag = ;
C->ptr.tp->ptr.hp->ptr.hp->atom = 'b';
C->ptr.tp->ptr.hp->ptr.tp = (Glist)malloc(sizeof(Glist));
// 存放子表(c,d),表头为c,表尾为d
C->ptr.tp->ptr.hp->ptr.tp->tag = ;
C->ptr.tp->ptr.hp->ptr.tp->ptr.hp = (Glist)malloc(sizeof(Glist));
C->ptr.tp->ptr.hp->ptr.tp->ptr.hp->tag = ;
C->ptr.tp->ptr.hp->ptr.tp->ptr.hp->atom = 'c';
C->ptr.tp->ptr.hp->ptr.tp->ptr.tp = (Glist)malloc(sizeof(Glist));
// 存放表尾d
C->ptr.tp->ptr.hp->ptr.tp->ptr.tp->tag = ;
C->ptr.tp->ptr.hp->ptr.tp->ptr.tp->ptr.hp = (Glist)malloc(sizeof(Glist));
C->ptr.tp->ptr.hp->ptr.tp->ptr.tp->ptr.hp->tag = ;
C->ptr.tp->ptr.hp->ptr.tp->ptr.tp->ptr.hp->atom = 'd';
C->ptr.tp->ptr.hp->ptr.tp->ptr.tp->ptr.tp = NULL;
return C;
}
结点结构的另一种表示方式
除了上边的那种表示结点的方式,还可以采用另外一种表示形式,不同在于:表结点和原子结点都添加了一个指向下一个数据元素的指针;而子表结点中只保留了指向表头结点的指针,删除了指向表尾的指针。
图3 广义表的另一种结点结构
代码表示为:
typedef struct GLNode
{
int tag; //标志域
union
{
int atom; //原子结点的值域
struct GLNode *hp; //子表结点的指针域,hp指向表头
};
struct GLNode *tp; //这里的tp相当于链表的next指针,用于指向下一个数据元素
}*Glist;
例如,用这种结构结构表示C = (a,(b,c,d)),效果图为:
图4 广义表C的结构示意图
实现代码:
Glist creatGlist(Glist C)
{
C = (Glist)malloc(sizeof(Glist));
C->tag = ;
C->hp = (Glist)malloc(sizeof(Glist));
C->tp = NULL;
// 表头原子a
C->hp->tag = ;
C->atom = 'a';
C->hp->tp = (Glist)malloc(sizeof(Glist));
C->hp->tp->tag = ;
C->hp->tp->hp = (Glist)malloc(sizeof(Glist));
C->hp->tp->tp = NULL;
// 原子b
C->hp->tp->hp->tag = ;
C->hp->tp->hp->atom = 'b';
C->hp->tp->hp->tp = (Glist)malloc(sizeof(Glist));
// 原子c
C->hp->tp->hp->tp->tag = ;
C->hp->tp->hp->tp->atom = 'c';
C->hp->tp->hp->tp->tp = (Glist)malloc(sizeof(Glist));
// 原子d
C->hp->tp->hp->tp->tp->tag = ;
C->hp->tp->hp->tp->tp->atom = 'd';
C->hp->tp->hp->tp->tp->tp = NULL;
return C;
}
总结
在编写代码时,一定要注意不要破坏广义表中数据元素之间的关系,例如:C1 = (a,b,c,d)和 C2 = (a,(b,c),d),两个广义表中数据元素是一样的,但是数据元素之间的关系不同,在 C1 中,各原子之间是并列的,而 C2 中,原子 a 和子表 (b,c) 和 d 是并列的。
补:M元多项式的表示
例如:
这是一个3元多项式(有3个变量:x,y,z),使用广义表表示M元多项式,首先需要对多项式做一下变形:
经过变形后,P(x,y,z)可以这样表示:
经过两轮转化后,P这个 3 元多项式分解成了由 A 多项式和 B 多项式组成的一元多项式(只有一个变元 z ),而 A 也变成了由 C 多项式和 D 多项式组成的一元多项式,…。
当全部转化成能用一元多项式表示时,每一个一元多项式只需要存储各项的指数和系数就可以了。
广义表中每个结点的构成如图5所示:
图5 多项式结点构成
代码表示:
typedef struct MPNode
{
int tag; //区分原子结点和子表结点(0代表原子;1代表子表)
int exp; //存放指数域
union
{
int coef; //存放多项式的系数
struct MPNode *hp; //当多项式系数为子表时,用它
};
struct MPNode *tp; //相当于线性链表的next,指向下一个数据元素
}*MPList;
实现代码:
MPList initP(MPList P)
{
char a[] = "xyz";
MPList F = (MPList)malloc(sizeof(MPList));
F->tag = ;
F->exp = ; // 表示F这个一员多项式中的变元位a[0],也就是x
F->hp = NULL;
F->tp = (MPList)malloc(sizeof(MPList));
F->tp->tag = ;
F->tp->exp = ; // x的指数为0
F->tp->coef = ; // 系数为2
F->tp->tp = NULL; // tp截止,说明F=2;
MPList E = (MPList)malloc(sizeof(MPList));
E->tag = ;
E->exp = ; // E中变元位a[0],即x
E->hp = NULL;
E->tp = (MPList)malloc(sizeof(MPList));
E->tp->tag = ;
E->tp->exp = ;
E->tp->coef = ;
E->tp->tp = (MPList)malloc(sizeof(MPList));
E->tp->tp->tag = ;
E->tp->tp->exp = ;
E->tp->tp->coef = ;
E->tp->tp->tp = NULL;// 截止,E=1*x4+6*x3(x后为它的指数)
MPList D = (MPList)malloc(sizeof(MPList));
D->tag = ;
D->exp = ;// D中变元为a[0],即x
D->hp = NULL;
D->tp = (MPList)malloc(sizeof(MPList));
D->tp->tag = ;
D->tp->exp = ;
D->tp->coef = ;
D->tp->tp = NULL; // 截止,D=3*x5(5是x的指数);
MPList C = (MPList)malloc(sizeof(MPList));
C->tag = ;
C->exp = ; // C中变元为a[0]=x;
C->hp = NULL;
C->tp = (MPList)malloc(sizeof(MPList));
C->tp->tag = ;
C->tp->exp = ;
C->tp->coef = ;
C->tp->tp = (MPList)malloc(sizeof(MPList));
C->tp->tp->tag = ;
C->tp->tp->exp = ;
C->tp->tp->coef = ;
C->tp->tp->tp = NULL; // C=1*x10+2*x6
MPList B = (MPList)malloc(sizeof(MPList));
B->tag = ;
B->exp = ; // B中变元为a[1]=y
B->hp = NULL;
B->tp = (MPList)malloc(sizeof(MPList));
B->tp->tag = ;
B->tp->exp = ;
B->tp->hp = E;
B->tp->tp = (MPList)malloc(sizeof(MPList));
B->tp->tp->tag = ;
B->tp->tp->exp = ;
B->tp->tp->hp = F;
B->tp->tp->tp = NULL; // B=E*y4+F*x1;
MPList A = (MPList)malloc(sizeof(MPList));
A->tag = ;
A->exp = ; // A中变元为a[1]=y;
A->hp = NULL;
A->tp = (MPList)malloc(sizeof(MPList));
A->tp->tag = ;
A->tp->exp = ;
A->tp->hp = C;
A->tp->tp = (MPList)malloc(sizeof(MPList));
A->tp->tp->tag = ;
A->tp->tp->exp = ;
A->tp->tp->hp = D;
A->tp->tp->tp = NULL; // A=C*y3+D*y2;
P = (MPList)malloc(sizeof(MPList));
P->tag = ;
P->exp = ; // 表示表元的数量
P->hp = (MPList)malloc(sizeof(MPList));
P->tp = NULL;
P->hp->tag = ;
P->hp->exp = ; // P中变元为a[2]=z;
P->hp->hp = NULL;
P->hp->tp = (MPList)malloc(sizeof(MPList));
P->hp->tp->tag = ;
P->hp->tp->exp = ;
P->hp->tp->hp = A;
P->hp->tp->tp = (MPList)malloc(sizeof(MPList));
P->hp->tp->tp->tag = ;
P->hp->tp->tp->exp = ;
P->hp->tp->tp->hp = B;
P->hp->tp->tp->tp = (MPList)malloc(sizeof(MPList));
P->hp->tp->tp->tp->tag = ;
P->hp->tp->tp->tp->exp = ;
P->hp->tp->tp->tp->coef = ;
P->hp->tp->tp->tp->tp = NULL; // P=A*z2+B*z1+15
return P;
}
数据结构28:广义表及M元多项式的更多相关文章
- javascript实现数据结构:广义表
原文:javascript实现数据结构:广义表 广义表是线性表的推广.广泛用于人工智能的表处理语言Lisp,把广义表作为基本的数据结构. 广义表一般记作: LS = (a1, a2, ..., an ...
- 数据结构:广义表的实现(Java)
广义表的简单理解在这篇博文中:https://blog.csdn.net/lishanleilixin/article/details/87364496,在此不做赘述. Java实现广义表: pack ...
- 数据结构 c++ 广义表
// CTest.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include <iostream> #include &l ...
- 数据结构5.4_m元多项式的表示
三元多项式表示如下: P(x,y,z) = x10y3z2 + 2x6y3z2 + 3x5y2z2 + x4y4z + 6x3y4z + 2yz + 15 然后对式子进行变形: P(x,y,z)=(( ...
- 数据结构(C语言第2版)-----数组,广义表,树,图
任何一个算法的设计取决于选定的数据结构,而算法的实现依赖于采用的存储结构. 之前线性表的数据元素都是非结构的原子类型,元素的值是不可再分的.下面学习的这两个线性表是很特殊的,其中数据元素本身也可能是一 ...
- 数据结构算法C语言实现(十九)--- 5.5&5.6&5.7广义表
一.简述 传说Lisp的基本数据结构就是广义表,广义表也是具有典型递归属性的数据结构,此外,由于建表要处理字符串,用C语言处理起来也是一脸懵逼.....最后自己还想写一个将广义表还原成字符串的函数,一 ...
- 广义表操作 (ava实现)——广义表深度、广义表长度、打印广义表信息
广义表是对线性表的扩展——线性表存储的所有的数据都是原子的(一个数或者不可分割的结构),且所有的数据类型相同.而广义表是允许线性表容纳自身结构的数据结构. 广义表定义: 广义表是由n个元素组成的序列: ...
- 【C/C++】实现数据结构广义表
1. 广义表的定义 每个元素可以为Atom,原子,也可以为线性表. 线性表的推广.线性表元素有唯一的前驱和后继,为线性表,而广义表是多层次的线性表 表头:第一个元素,可能是 ...
- 数据结构(C语言版)-第4章 串、数组和广义表
补充:C语言中常用的串运算 调用标准库函数 #include<string.h> 串比较,strcmp(char s1,char s2) 串复制,strcpy(char to,char f ...
随机推荐
- handlebars中的partial
高级玩家:partial 比较推崇使用分页来实现组件化.分页跟helper一样需要先注册.在hbs模块中可以批量注册,比较简单. hbs.registerPartials(__dirname + '/ ...
- 冷扑大师AI简史:你用德扑来游戏,人家用来发Science
前言 人类又输了...... 创新工场组织的一场“人工智能和顶尖牌手巅峰表演赛中”,机器人AI冷扑大师赢了人类代表队龙之队 792327 记分牌,最后 200 万奖励归机器人所有. 在围棋项目上人类的 ...
- windows 修改端口数据及连接时间
最近线上遇到windows机器访问其他机器的时候失败的情况.实际就是本地的端口不够用造成的. D:\>netsh interface ipv4 show dynamicportrange pro ...
- Ok6410裸机驱动学习(三)C语言内嵌汇编
1.C语言内嵌汇编使用方法 C内嵌汇编以关键字”_asm_或asm开始,下辖4个部分,各部分之间用“:”分开,第一部分是必须写的,后面3个部分可以省略,但是分号:不能省略 优化后的代码 2.汇编程序框 ...
- DAY10-MYSQL初识
一 数据库管理软件的由来 基于我们之前所学,数据要想永久保存,都是保存于文件中,毫无疑问,一个文件仅仅只能存在于某一台机器上. 如果我们暂且忽略直接基于文件来存取数据的效率问题,并且假设程序所有的组件 ...
- [Python Study Notes]pd.read_csv()函数读取csv文件绘图
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' ...
- 【总结整理】WebGIS基础
1.万维网:www是world wide web的简称是在超文本基础上形成的信息网 2.互联网:即广域局域网及单机按照一定的通讯协议组成的国际计算机网络 3.WebGIS:网络地理信息系统,指基于In ...
- .NET回归 HTML----表单元素(1)和一些常用的标记
表单就是-----用于搜集不同类型的用户输入. 表单元素指的是不同类型的 input 元素.复选框.单选按钮.提交按钮等等. 首先将表单元素分为三个类型.文本类,按钮类,选择类. 表单可以嵌套在表中, ...
- Opengl创建几何实体——四棱锥和立方体
//#include <gl\glut.h>#include <GL\glut.h>#include <iostream> using namespace std; ...
- c语言实战: 计算时间差
计算时间差有两种,一种是把时间都转化为分钟数,一种是把时间都转化为小时,后者是会用到除法所以不可避免产生浮点数,所以我们选择转化为分钟数来计算. //题目:给定两个时间点计算它们的时间差,比如,1:5 ...