zoukankan      html  css  js  c++  java
  • 线性表

    一、线性结构的特点

      线性表是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); // 多项式相乘
           
  • 相关阅读:
    最短路必经点(边)
    [HNOI2008]越狱
    【模版】卢卡斯定理
    偶数
    [USACO17FEB]Why Did the Cow Cross the Road I S
    [USACO17FEB]Why Did the Cow Cross the Road II S
    [USACO07NOV]电话线Telephone Wire
    [JSOI2007]祖码Zuma
    单人纸牌_NOI导刊2011提高(04)
    [USACO13OPEN]重力异常
  • 原文地址:https://www.cnblogs.com/soldierback/p/10557037.html
Copyright © 2011-2022 走看看