一、线性结构的特点
线性表是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); // 多项式相乘