1.多项式的表示
例:一元多项式及其运算
一元多项式:
主要运算:多项式相加,相减,相乘
①顺序存储结构直接表示
:项 的系数
②顺序存储结构表示非零项
用结构数组表示:把每个多项式看作为 二元组的集合
例: 和
③链表结构存储非零项
链表中每个结点存储多项式的一个非零项,其中包括系数和指数两个数据域一个指针域。
coef | expon | link |
结构定义:
typedef struct PolyNode* Polynominal;
struct PolyNode{
int coef;
int expon;
Polynominal link;
}
2.什么是线性表
①多项式表示问题的启示:
同个问题可以有不同的存储方法
有一类共性问题:有序线性序列和组织和管理
②线性表
线性表的定义:
由同类数据元素构成的有序序列的线性结构
线性表的抽象数据类型描述:
数据对象集:n(>0)个元素构成有序序列
操作集(主要):
1. List MakeEmpty()
2.ElementType FindKth(int K,List L)
3.int Find(ElementType X,List L)
4.void Insert(ElementType X,int i,List L)
5.void Delete(int i,List L)
6.int Length(List L)
③线性表的顺序存储实现:利用数组的连续空间顺序存放线性表的各元素
Data | ···· | ···· | ···· | --- |
typedef struct LNode* List;
struct LNode{
ElmentType Data[MAXSIZE];
int last;
};
struct LNode L;
List PtrL;
访问下标i的元素:L.Data[i] 或PtrL->Data[i]
数组的长度:L.last+1 或 PtrL->last+1
主要操作的实现:
a.初始化:List MakeEmpty()
List MakeEmpty(){
List PtrL;
PtrL=(List)malloc(sizeof(struct LNode);
PtrL->last=-1;
return PtrL;
}
b.查找: int Find(ElementType X,List 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;
}
c.插入:void Insert(ElementType X,int i,List PtrL)
void Insert(ElementType X,int i,List PtrL){
int j;
if(PtrL->last==MaxSize-1){
printf("表满");
return;
}
if(i<1||i>PtrL->last+2){
printf("位置不合法");
return;
}
for(j=PtrL->last;j>=i-1;j--)
PtrL->Data[j+1]=PtrL->Data[j];
PtrL[i-1]=X;
PtrL->last++;
return;
}
d.删除:void Delete(int i,List PtrL)
void Delete(int i,List PtrL){
int j;
if(i<1||i>PtrL->last+1){
printf("不存在第%d个元素",i);
return;
}
for(j=i;j<=PtrL->last;j++)
PtrL[j-1]=PtrL[j];
PtrL->last--;
return;
}
④线性表的链式存储实现
不要求逻辑上相邻的两个元素物理上也相邻,通过“链”建立起数据元素之间的逻辑关系
typedef struct LNode* List;
struct LNode{
ElementType Data;
List Next;
};
struct LNode L;
List PtrL;
主要操作的实现:
a.求表长:int Length(List PtrL)
int Length(List PtrL){
List p=PtrL;
int j=0;
while(p){
p=p->next;
j++;
}
return j;
}
b.查找
(1)a按序号查找:FindKth
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)按值查找:Find
List Find(ElementType X,List PtrL){
List p=PtrL;
while(p!=NULL&&p->data!=X)
p=p->next;
return p;
}
c.插入:
(1) 先构造一个结点,用s指向
(2) 再找到链表的第i-1个结点,用p指向
(3) 然后修改结点,插入结点(s->next=p->next;p->next=s)
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("参数i错");
return NULL;
}
else{
s=(List)malloc(sizeof(struct LNode));
s->Data=X;
s->next=p->next;
p->next=s;
return PtrL;
}
}
d.删除
(1) 先找到链表第i-1个结点,用p指向
(2) 再用指针s指向要删除结点(p的下一个节点)
(3) 然后修改指针,删除s所指向结点(p->next=s->next)
(4) 最后释放s所指向结点的空间 (free(s))
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("第%d个结点不存在",i-1);
return NULL;
}else if(p->next==NULL){
printf("第%d个结点不存在",i);
return NULL;
}else{
s=p->Next;
p->next=s->next;
free(s);
return PtrL;
}
⑤广义表
例:给定二元多项式
可以表示为关于x的一元多项式:
广义表定义:
是线性表的推广
广义表中,元素不仅可以为单元素还可以是另一个广义表
typedef struct GNode* GList;
struct GNode{
int Tag; /* 标志域:0表示结点是单元素,1表示结点是广义表 */
union{ /* 子表指针域SubList与单元素数据Data复用 */
ElementType Data;
GList SubList;
}URegion;
GList Next;
};
Tag | Data ———— SubList |
Next |
⑥多重链表
多重链表的特性:
多重链表中的结点的指针域有多个;
但包含两个指针域的链表不一定是多重链表(如双向链表)
例:采用一种典型的多重链表——十字链表来存储稀疏矩阵
结点的数据域:行坐标Row,列坐标Col,数值Value;
每个结点通过两个指针域,把同行、同列穿起来
行指针Right
列指针Down
用一个是标识域Tag区分头结点和非0元素结点
头结点的标识值为“Head”,矩阵非0元素节点的标识值为“Term”
Tag | ||
Down | URegion | Right |
Term | ||
Down | Row | Col —————— Value |
Right |
Head | ||
Down | Next | Right |