第二章 线性表
1 线性表的类型定义
    1)抽象数据类型线性表的定义如下:
    ADT List
    {
        数据对象:D = {|ElemSet, i = 1, 2, …, n, n0}
              数据关系:R1 = {<, > | , D, i = 2,…, n}
              基本操作:
                     InitList(&L)
                            操作结果:构造一个空的线性表L
                     DestroyList(&L)
                            初始条件:线性表L已存在。
                           操作结果:销毁线性表L
                     ClearList(&L)
                            初始条件:线性表L已存在。
                            操作结果:将L重置为空表。
                     ListEmpty(L)
                            初始条件:线性表L已存在。
                            操作结果:若L为空表,则返回TRUE,否则返回FALSE
                     ListLengthL
                            初始条件:线性表L已存在。
                            操作结果:返回L中数据元素的个数。
                     GetElem(L, i, &e)
                            初始条件:线性表L已存在,1iListLength(L)
                            操作结果:用e返回L中第i个数据元素的值。
                     LocateElem(L, e, compare())
                            初始条件:线性表L已存在,compare()是数据元素判定函数。
                                              操作结果:返回L中第1个与e满足关系compare()的数据元素的位序。                                                                                           若这样的数据元素不存在,则返回值为0
                                       PriorElem(L, cur_e, &pre_e)
                                              初始条件:线性表L已存在。
                                              操作结果:若cur_eL的数据元素,且不是第一个,则用pre_e返回它                                                                的前驱,否则操作失败,pre_e无定义。
                     NextElem(L, cur_e, &next_e)
                            初始条件:线性表L已存在。
                            操作结果:若cur_eL的数据元素,且不是最后一个,则用next_e返回                                      它的后继,否则操作失败,next_e无定义。
                     ListInsert(&L, i, e)
                            初始条件:线性表L已存在, 1iListLength(L)+1
                            操作结果:在L中第i个位置之前插入新的数据元素eL的长度加1
                     ListDelete(&L, i, &e)
                            初始条件:线性表L已存在且非空,1iListLength(L)
                            操作结果:删除L的第i个数据元素,并用e返回其值,L的长度减1
                     ListTraverse(L, visit())
                            初始条件:线性表L已存在。
                            操作结果:依次对L的每个数据元素调用函数visit(),一旦visit()失败,                                               则操作失败。
       }ADT List
       2)假设利用两个线性表LALB分别表示两个集合AB,现要求一个新的集合A=AB
       void union(List &La, List Lb)
       {
              La.len = ListLength(La);
              Lb.len = ListLength(Lb);
              for (i = 1; i <= Lb.len; i ++)
              {
                     GetElem(Lb, i, e);
                     if (!LocateElem(La, e, equal))
                            ListInsert(La, ++ La.len, e);
              }
       }
       3)已知线性表LALB中的数据元素按值非递减有序排列,现要求将LALB归并为一个新的线性表LC,且LC中的数据元素仍按值非递减有序排列。
       void MergeList(List La, List Lb, List &Lc)
       {
              InitList(Lc);
             i = j = 1;
              k = 0;
              La.len = ListLength(La);
              Lb.len = ListLength(Lb);
              while ((i <= La.len) && (j <= Lb.len))
              {
                     GetElem(La, i, ai);
                     GetElem(Lb, j, bj);
                     if (ai <= bj)
                     {
                            ListInsert(Lc, ++k, ai);
                            ++ i;
                     }
                     else
                     {
                            ListInsert(Lc, ++k, bj);
                            ++ j;
                     }
              }
              while (i <= La.len)
              {
                     GetElem(La, i ++, ai);
                     ListInsert(Lc, ++k, ai);
              }
              while (j <= Lb.len)
              {
                     GetElem(Lb, j ++, bj);
                     ListInsert(Lc, ++ k, bj);
              }
       }
 
2 线性表的顺序表示和实现
       线性表的顺序存储结构是一种随机存取的存储结构。
       线性表的动态分配顺序存储结构:
       #define   LIST_INIT_SIZE          100
       #define    LISTINCREMENT        10
       typedef struct
       {
              ElemType       *elem;
              int                  length;
              int                  listsize;
       }SqList;
       1)顺序表的初始化操作:
       Status InitList_Sq(SqList &L)
       {
              L.elem = (ElemType*)malloc(LIST_INIT_SIZE*sizeof(ElemType));
              if (!L.elem)
                     exit(OVERFLOW);
              L.length = 0;
              L.listsize = LIST_INIT_SIZE;
              return OK;
       }
       2)顺序表的插入操作:
       Status ListInsert_Sq(SqList &L, int i, ElemType e)
       {
              if (i < 1 || i > L.length + 1)
                     return ERROR;
              if (L.length >= L.listsize)
              {
                     newbase=(ElemType*)realloc(L.elem,(L.listsize+LISTCREMENT)
                                   *sizeof(ElemType));
                     if (!newbase)
                            exit(OVERFLOW);
                     L.elem = newbase;
                     L.listsize += LISTINCREMENT;
              }
              q = &(L.elem[i-1]);
              for (p = &(L.elem[L.length - 1]); p >= q; -- p)
                     *(p + 1) = *p;
              *q = e;
              ++ L.length;
              return OK;
       }
       其时间复杂度为O(n)
       3)顺序表的删除操作:
       Status ListDelete_Sq(SqList &L, int i, ElemType &e)
       {
              if ((i < 1) || (i > L.length))
                     return ERROR;
              p = &(L.elem[i-1]);
              e = *p;
              q = L.elem + L.length -1;
              for (++ p; p <= q; ++ p)
                     *(p - 1) = *p;
              -- L.length;
              return OK;
       }
       其时间复杂度为O(n)
       4)顺序表的查找操作:    
       int LocateElem_Sq(SqList L, ElemType e, Status (*compare)(ElemType, ElemType))
       {
              i = 1;
              p = L.elem;
              while (i <= L.length && !(*compare)(*p ++, e))
                     ++ i;
              if (i <= L.length)
                     return i;
              else
                     return 0;
       }
       其时间复杂度为O(L.length)
       5)顺序表的合并操作:
       void MergeList_Sq(SqList La, SqList Lb, SqList &Lc)
       {
              pa = La.elem;
              pb = Lb.elem;
              Lc.listsize = Lc.length = La.length + Lb.length;
              pc = Lc.elem = (ElemType*)malloc(Lc.listsize * sizeof(ElemType));
              if (!Lc.elem)
                     exit(OVERFLOW);
              pa_last = La.elem + La.length -1;
              pb_last = Lb.elem + Lb.length -1;
              while (pa <= pa_last && pb <= pb_last)
              {
                     if (*pa <= *pb)
                            *pc ++ = *pa ++;
                     else
                            *pc ++ = *pb ++;
              }
              while (pa <= pa_last)
                     *pc ++ = *pa ++;
              while (pb <= pb_last)
                     *pc ++ = *pb ++;
       }
       其时间复杂度为O(La.length + Lb.length )