一、线性结构的特点

  线性表是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); // 多项式相乘