实例:多项式f ( x ) 的表示。
数组各分量对应多项式的各项:
a【i】:项 x ^ i 的系数 ai 。
两个多项式相加:两个数组对应分量的相加。
缺点:表示多项式 x + x ^ 2000 时存在巨大的空间浪费。
用结构数组(二维数组)表示:数组分量是由系数 ai 、指数 i 组成的结构,对应一个非零项。
注意:存储时需要将指数大小从小到大排序,方便之后的运算。
链表中每个结点存储多项式中的一个非零项,包括系数和指数两个数据域以及一个指针域
coef | expon | link |
---|
typedef struct PolyNode *Polynomial;
struct PolyNode {
int coef;
int expon;
Polynomial link;
};
线性表(Linear List):由同类型数据元素构成有序序列的线性结构
基本结构如下:
typedef struct LNode *List;
struct LNode {
ElementType Data[MAXSIZE];
int last;
};
struct LNode L;
List PtrL;
List MakeEmpty()
{
List PtrL;
PtrL = (List)malloc(sizeof(struct LNode));
PtrL -> Last = -1;
return PtrL;
}
int Find(ElementType X, List PtrL)
{
int i = 0;
while (i <= PtrL->Last && PtrL->Data[i] != X)
i++;
if (i > PtrL->Last)
return -1;
else
return i;
}
void Insert(ElementType X, int i, List PtrL)
{
int j;
if (PtrL->Last == MAXSIZE - 1) {
printf('FULL');
return;
}
if (i<1 || i>PtrL->Last + 2) {
printf('No right');
return;
}
for (j = PtrL->Last;j >= i - 1;j--)
PtrL->Data[j + 1] = PtrL->Data[j];
PtrL->Data[i - 1] = X;
PtrL->Last++;
return;
}
void Delete(int i, List PtrL)
{
int j;
if (i<1 || i>PtrL->Last + 1) {
printf("The %d item(s) no exist.", i);
return;
}
for (j = i;j <= PtrL->Last;j++)
PtrL->Data[j - 1] = PtrL->Data[j];
PtrL->Last--;
return;
}
基本结构如下:
typedef struct LNode *List;
struct LNode {
ElementType Data[MAXSIZE];
List Next;
};
struct LNode L;
List PtrL;
int Length(List PtrL)
{
List p = PtrL;
int j = 0;
while (p) {
p = p->Next;
j++;
}
return j;
}
(1)按序号查找:
List FindKth(int K, List PtrL)
{
List p = PtrL;
int i = 1;
while (p != NULL && i < K) {
p = p->Next;
i++;
}
if (i == K)
return p;
else
return NULL;
}
(2)按值查找:
List Find(ElementType X, List PtrL)
{
List p = PtrL;
while (p != NULL && p->Data != X)
p = p->Next;
return p;
}
List Insert(ElementType X, int i, List PtrL)
{
List p, s;
if (i == 1) {
s = (List)malloc(sizeof(struct LNode));
s->Data = X;
s->Next = PtrL;
return s;
}
p = Findkth(i - 1, PtrL);
if (p == NULL) {
printf("Parameter i Error!");
return NULL;
}
else
{
s=(List)malloc(sizeof(struct LNode));
s->Data = X;
s->Next = p->Next;
p->Next = s;
return PtrL;
}
}
List Delete(int i, List PtrL)
{
List p, s;
if (i == 1) {
s = PtrL;
if (PtrL != NULL)
PtrL = PtrL->Next;
else
return NULL;
free(s);
return PtrL;
}
p = FindKth(i - 1, PtrL);
if (p = NULL) {
printf("The %d intersection no exist.", i - 1);
return NULL;
}
else if (p->Next == NULL) {
printf("The %d intersection no exist.", i);
return NULL;
}
else {
s = p->Next;
p->Next = s->Next;
free(s);
return PtrL;
}
}
例子:如何表示二元多项式?
基本格式如下:
typedef struct GNode *GList;
struct GNode {
int Tag;
// 标志域:0表示结点是单元素;1表示结点是广义表。
union {
// 字表指针域SubList与单元素数据域Data复用,共用存储空间。
ElementType Data;
GList SubList;
}
URegion;
GList Next;
};
实例:矩阵的表示。
若用二维数组表示的话,会有两个缺陷:
【分析】采用一种典型的多重链表——十字链表来存储稀疏矩阵
只存储矩阵非0元素项
结点的数据域:行坐标Row、列坐标Col、数值Value
每个结点通过两个指针域,把行列串起来
1、行指针(向右指针)Right
2、列指针(向下指针)Down
十字链表代码示例:
#include
#include
/*十字链表的结构类型定义如下:*/
typedef struct OLNode
{
int row,col; /*非零元素的行和列下标*/
int value;
struct OLNode *right; /*非零元素所在行表、列表的后继链域*/
struct OLNode *down;
} OLNode, *OLink;
typedef struct
{
OLink *row_head; /*行、列链表的头指针向量*/
OLink *col_head;
int m,n,len; /*稀疏矩阵的行数、列数、非零元素的个数*/
} CrossList;
/*建立稀疏矩阵的十字链表的算法*/
void CreateCrossList(CrossList *M)
{
int m, n, t, i, j, e;
OLNode* p;
OLNode* q;
/*采用十字链表存储结构,创建稀疏矩阵M*/
scanf("%d%d%d", &m,&n,&t); /*输入M的行数,列数和非零元素的个数*/
M->m=m;
M->n=n;
M->len=t;
if(!(M->row_head=(OLink *)malloc(m*sizeof(OLink))))
exit(OVERFLOW);
if(!(M->col_head=(OLink * )malloc(n*sizeof(OLink))))
exit(OVERFLOW);
/*初始化行、列,头指针指向量,各行、列链表为空的链表*/
for(int h=0; h<m+1; h++)
{
M->row_head[h] = NULL;
}
for(int t=0; t<n+1; t++)
{
M->col_head[t] = NULL;
}
for(scanf("%d%d%d", &i,&j,&e); e!=0; scanf("%d%d%d", &i,&j,&e))
{
if(!(p=(OLNode *)malloc(sizeof(OLNode))))
exit(OVERFLOW);
p->row=i;
p->col=j;
p->value=e; /*生成结点*/
if(M->row_head[i]==NULL)
M->row_head[i]=p;
p->right=NULL;
else
{
/*寻找行表中的插入位置*/
for(q=M->row_head[i]; q->right&&q->right->col<j; q=q->right); /*空循环体*/
p->right=q->right;
q->right=p; /*完成插入*/
}
if(M->col_head[j]==NULL)
M->col_head[j]=p;
p->down=NULL;
else
{
/*寻找列表中的插入位置*/
for(q=M->col_head[j]; q->down&&q->down->row<i; q=q->down); /*空循环体*/
p->down=q->down;
q->down=p; /*完成插入*/
}
}
}