一、线性结构的特点
线性表是n个数据元素的有限序列,具有如下几个特点:
1)存在唯一的第一个元素;
2)存在唯一的最后一个元素;
3)除了第一个和最后一个元素外,其余的都只有一个前驱和一个后继
一个数据元素可以由多个数据项组成:
二、抽象数据类型线性表的定义
ADT List {
数据对象:D = {ai | ai ∈ ElemSet,i = 1,2,...,n, n ≥ 0}
数据关系:R = {<ai-1, ai> | ai-1,ai ∈ D,i=2,...,n}
基本操作:
InitList(&L);
操作结果:构造一个空的线性表L
DestroyList(&L);
初始条件:线性表L已存在
操作结果:销毁线性表
ClearList(&L);
初始条件:线性表L已存在
操作结果:将L重置为空表
ListEmpty(L);
初始条件:线性表L已存在
操作结果:若 L 为空表,则返回 TRUE,否则返回 FALSE
ListLength(L);
初始条件:线性表 L 已存在
操作结果:返回 L 中元素个数
PriorElem(L, cur_e, &pre_e);
初始条件:线性表 L 已存在。
操作结果:若 cur_e 是 L 中的数据元素,则用 pre_e 返回它的前驱,否则操作失败,pre_e 无定义
NextElem(L, cur_e, &next_e);
初始条件:线性表 L 已存在
操作结果:若 cur_e 是 L 中的数据元素,则用 next_e 返回它的后继,否则操作失败,next_e 无定义
GetElem(L, i, &e);
初始条件:线性表 L 已存在,1 ≤ i ≤ LengthList(L)
操作结果:用 e 返回 L 中第 i 个元素的值
LocateElem(L, e, compare( ));
初始条件:线性表 L 已存在,compare( ) 是元素判定函数
操作结果:返回 L 中第1个与 e 满足关系 compare( ) 的元素的位序。若这样的元素不存在,则返回值为0
ListTraverse(L, visit( ));
初始条件:线性表 L 已存在,visit( ) 为元素的访问函数
操作结果:依次对 L 的每个元素调用函数 visit( )。一旦 visit( ) 失败,则操作失败
PutElem(&L, i, &e);
初始条件:线性表L已存在,1≤i≤LengthList(L)
操作结果:L 中第 i 个元素赋值同 e 的值。
ListInsert(&L, i, e);
初始条件:线性表 L 已存在,1≤i≤LengthList(L)+1
操作结果:在 L 的第 i 个元素之前插入新的元素 e,L 的长度增1
ListDelete(&L, i, &e);
初始条件:线性表 L 已存在且非空,1≤i≤LengthList(L)
操作结果:删除 L 的第 i 个元素,并用 e 返回其值,L 的长度减1
} ADT List
三、线性表的顺序表示
1)特点
用一组地址连续的存储空间一次存储线性表中的元素
2)动态分配顺序存储结构
#define LIST_INIT_SIZE 100 // 存储空间的初始分配量
#define LISTINCREAMENT 10 // 分配增量
typedef struct {
ElemType *elem; // 存储空间基址
int length; // 当前长度
int listsize; // 当前分配的存储容量(以 sizeof(ElemType)为单位)
};
3)以上结构的初始化代码
Status InitList_Sq(SqList &L) {
//构造一个空的线性表
L.elem = (ElemType *)malloc(LIST_INIT_SIZE * sizeof(ElemType));
if (! L.elem) { exit(OVERFLOW); } // 存储分配失败
L.length = 0; // 空表长度为0
L.listsize = LIST_INIT_SIZE; // 初始存储容量
return OK;
}
四、线性表的链式表示
1)特点
用一组任意的存储单元存储线性表中的数据元素
2)单链表存储结构
typedef struct LNode {
ElemType data;
struct LNode *next;
} LNode, *LinkList;
3)静态单链表存储结构
#define MAXSIZE 1000 // 链表的最大长度
typedef struct {
ElemType data;
int cur;
} component, SLinkList [ MAXSIZE ];
4)循环链表
将尾结点的指针域指向表头即构成循环链表
5)双向链表存储结构
typedef struct DuLNode {
ElemType data;
struct DuLNode *prior;
struct DuLNode *next;
} DuLNode, *DuLinkList;
6)一个带头节点的线性表类型定义
typedef struct LNode { // 节点类型
ElemType data;
struct LNode *next;
} *Link, *Position;
typedef struct { // 链表类型
Link head, tail; // 分别指向线性链表中的头结点和最后一个结点
int len; // 指示线性链表中数据元素的个数
} LinkList;
Status MakeNode(Link &p, ElemType e);
// 分配由p指向的值为e的结点,并返回OK;若分配失败,则返回ERROR
void FreeNode(Link &P);
// 释放p所指结点
Status InitLink(LinkList &L);
// 构造一个空的线性链表L
Status DestroyList(LinkList &L);
// 销毁线性链表L
Status ClearList(LinkList &L);
// 将线性表L重置为空表
Status InsFirst(Link h, Link s);
// 已知h指向线性链表的头结点,将s所指结点插入在第一个结点之前
Status DelFirst(Link h, Link &q);
// 已知h指向线性链表的头结点,删除链表中的第一个结点并以q返回
Status Append(LinkList &L, Link s);
// 将指针s所指的一串结点链接在线性表L的最后一个结点
// 之后,并改变链表L的尾指针指向新的尾结点
Status Remove(LinkList &L, Link &q);
// 删除线性链表中的尾结点并以q返回,改变L的尾指针指向新的尾结点
Status InsBefore(LinkList &L, Link &p, Link s);
// 已知p指向L中的一个结点,将s所指结点插入在p所指结点之前
// 并修改p指向新插入的结点
Status InsAfter(LinkList &L, Link &p, Link s);
// 已知p指向L中的一个结点,将s所指结点插入在p所指结点之后
// 并修改p指向新插入的结点
Status SetCurElem(Link &p, ElemType e);
// 已知p指向线性链表中的一个结点,用e更新p所指结点中数据元素的值
ElemType GetCurElem(Link p);
// 已知p指向链表中的一个结点,返回p所指结点中数据元素的值
Status ListEmpty(LinkList L);
// 若线性链表L为空表,则返回TRUE,否则返回FALSE
int ListLength(LinkList L);
// 返回线性链表L中元素个数
Position GetHead(LinkList L);
// 返回线性链表L中头结点的位置
Position GetLast(LinkList L);
// 返回线性链表L中最后一个结点的位置
Position PriorPos(LinkList L, Link p);
// 已知p指向线性链表L中的=一个结点,返回p所指结点的直接前驱的
// 位置,若无前驱,则返回NULL
Position NextPos(LinkList L, Link p);
// 已知p指向线性链表L中的一个结点,返回p所指结点的直接后继的
// 位置,若无后继,则返回NULL
Status LocateElem(LinkList L, int i, Link &p);
// 返回p指向线性链表L中第i个结点的位置并返回OK,i值不合法时返回ERROR
Position LocateElem(LinkList L, ElemType e, Status (*compare)(ElemType, ElemType));
// 返回线性链表L中第1个与e满足函数compare()判定关系的元素的
// 位置,若不存在这样的元素,则返回NULL
Status ListTraverse(LinkList L, Status ( * visit)());
// 依此对L的每个元素调用函数visit(),一旦visit()失败,则操作失败
五、一元多项式的表示及相加
1)抽象数据类型一元多项式的定义:
ADT Polynomial {
数据对象:D = {ai | ai ∈ TermSet, i = 1,2,...,m, m ≥ 0
TermSet中的每个元素包含一个表示系数的实数和表示指数的整数}
数据关系:R = {<ai-1, ai> | ai-1, ai ∈ D, 且ai-1中的指数值<ai中的指数值, i = 2,...,n}
基本操作:
CreatePolyn(&P, m);
操作结果:输入m项的系数和指数,建立一元多项式P
DestroyPolyn(&P);
操作条件:一元多项式P已存在
操作结果:销毁一元多项式P
PrintPolyn(P);
操作条件:一元多项式P存在
操作结果:打印输出一元多项式P
PolynLength(P);
操作条件:一元多项式P存在
操作结果:返回一元多项式P中的项数
AddPolyn(&Pa, &Pb);
操作条件:一元多项式Pa和Pb已存在
操作结果:完成多项式相加运算,即:Pa = Pb + Pb,并销毁一元多项式Pb
SubtractPolyn(&Pa, &Pb);
操作条件:一元多项式Pa和Pb已存在
操作结果:完成多项式相减运算,即:Pa = Pa - Pb,并销毁一元多项式Pb
MultiplyPolyn(&Pa, &Pb);
操作条件:一元多项式Pa和Pb已存在
操作结果:完成多项式相乘运算,即 :Pa = Pa x Pb,并销毁一元多项式Pb
} ADT Polynomial
2)抽象数据类型Polynomial的实现
typedef struct {
float coef; // 系数
int expn; // 指数
};
typedef LinkList polynomial; // 用带表头结点的有序链表表示多项式
/** ------------ 基本操作的函数原型 ------------ **/
void CreatePloyn(polynomial &P, int m); // 创建多项式
void DestroyPloyn(polynomial &P); // 销毁多项式
void PrintPloyn(polynomial P); // 打印多项式
int PolynLength(polynomial P); // 返回项数
void AddPolyn(polynomial &Pa, polynomial &Pb); // 多项式相加
void SubtractPolyn(polynomial &Pa, polynomial &Pb); // 多项式相减
void MultiplyPolyn(polynomial &Pa, polynomial &Pb); // 多项式相乘