线性表(顺序存储)

线性表

      线性结构特点

      有“头”元素有“尾”元素,中间的元素有“前驱”元素和“后继”元素 线性表是一个数据元素的有序(次序)集

      (1)集合中必存在唯一的一个“第一元素”;

      (2)集合中必存在唯一的一个 “最后元素” ;

      (3)除最后元素在外,均有 唯一的后继;

      (4)除第一元素之外,均有 唯一的前驱。

     抽象数据类型线性表的定义如下:

           ADT List {

                  数据对象: D={ ai | ai ∈ElemSet, i=1,2,...,n, n≥0 } {称 n 为线性表的表长; 称 n=0 时的线性表为空表。}

                 数据关系: R1={ <ai-1 ,ai >|ai-1 ,ai∈D, i=2,...,n } {设线性表为 (a1,a2, . . . ,ai,. . . ,an), 称 i 为 ai 在线性表中的位序。}

                基本操作:

                     结构初始化操作(添加)

                     结构销毁操作(删除)

                     引用型操作(查询)

                     加工型操作(修改)

           }ADT List

           结构初始化操作(添加) InitList( &L ) 操作结果:构造一个空的线性表L。

           结构销毁操作(删除) DestroyList( &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≤ListLength (L)。 操作结果:用 e 返回L中第 i 个元素的值。

           引用型操作(查询) LocateElem( L, e, compare( ) ) (定位函数) 初始条件:线性表L已存在,e为给定值, compare( )是元素判定函数。 操作结果:返回L中第1个与e满足关系compare( )的元素的位序。若这样的元素不存在,则返回值为0。

           引用型操作(查询) ListTraverse(L, visit( )) (遍历线性表) 初始条件:线性表L已存在,visit() 为某个访问函数。 操作结果:依次对L的每个元素调用函数visit( )。一旦visit( )失败,则操作失败。

           加工型操作(修改

           加工型操作(修改) ClearList( &L ) (线性表置空) 初始条件:线性表L已存在。 操作结果:将L重置为空表。

           加工型操作(修改) PutElem( &L, i, &e ) (改变数据元素的值) 初始条件:线性表L已存在,且 1≤i≤ListLength (L) 。 操作结果: L中第i个元素赋值同e的值。

           加工型操作(修改) ListInsert( &L, i, e ) (插入数据元素) 初始条件:线性表L已存在, 且 1≤i≤ListLength (L)+1 。 操作结果:在L的第i个元素之前插入新的元素e,L的长度增1。

           加工型操作(修改) ListDelete(&L, i, &e) (删除数据元素) 初始条件:线性表L已存在且非空, 1≤i≤LengthList(L) 。 操作结果:删除L的第i个元素,并用e返回其值,L的长度减1。

      数据结构代码(参考链接http://wenku.baidu.com/link?url=Iyjsczu_DGbiqTZlWDJt8u2BAfGI0XMPDyPI0Tz8ESEbvZRJbk6NlKl5O4g1eRvr-MoS7Kx14Tu4pqhn2Xrn-7KOc1E5xLHNwUQwokPFS6u)

       基本操作及算法

  1 #include<stdio.h>
  2 #include<stdlib.h>
  3 /*自定义*/
  4 #define LIST_INIT_SIZE 10 /* 线性表存储空间的初始分配量 */
  5 #define LISTINCREMENT 2 /* 线性表存储空间的分配增量 */
  6 #define INFEASIBLE 999999999/*超出线性表存储空间*/
  7 #define OK 1
  8 #define TRUE 1
  9 #define FALSE 0
 10 #define OVERFLOW 0/*溢出*/
 11 #define ERROR 0/*错误*/
 12 typedef int Status;
 13 typedef int ElemType;
 14  #define LIST_INIT_SIZE 10 /* 线性表存储空间的初始分配量 */
 15  #define LISTINCREMENT 2 /* 线性表存储空间的分配增量 */
 16  typedef struct
 17  {
 18    ElemType *elem; /* 存储空间基址 */
 19    int length; /* 当前长度 */
 20    int listsize; /* 当前分配的存储容量(以sizeof(ElemType)为单位) */
 21  }SqList;
 22 /*顺序表示的线性表(存储结构)的12个基本操作*/
 23 Status InitList(SqList &L)
 24 {
 25 /* 操作结果:构造一个空的顺序线性表 */
 26     L.elem=(ElemType*)malloc(LIST_INIT_SIZE*sizeof(ElemType));
 27     if(!L.elem)
 28       exit(OVERFLOW);
 29     L.length=0;
 30     L.listsize=LIST_INIT_SIZE;
 31     return OK;
 32 }
 33 Status DestroyList(SqList &L)
 34 {
 35 /* 初始条件:顺序线性表L已存在。操作结果:销毁顺序线性表L */
 36     free(L.elem);
 37     L.elem=NULL;
 38     L.length=0;
 39     L.listsize=0;
 40     return OK;
 41 }
 42 
 43 Status ClearList(SqList &L)
 44 {
 45 /* 初始条件:顺序线性表L已存在。操作结果:将L重置为空表 */
 46     L.length=0;
 47     return OK;
 48 }
 49 Status ListEmpty(SqList L)
 50 {
 51 /* 初始条件:顺序线性表L已存在。操作结果:若L为空表,则返回TRUE,否则返回FALSE */
 52     if(!L.length)
 53      return TRUE;
 54     else
 55       return FALSE;
 56 }
 57 ElemType ListLength(SqList L)
 58 {
 59 /* 初始条件:顺序线性表L已存在。操作结果:返回L中数据元素个数 */
 60     return L.length;
 61 }
 62 ElemType GetElem(SqList L,int i,ElemType &e)
 63 {
 64 /* 初始条件:顺序线性表L已存在,1≤i≤ListLength(L) */
 65 /* 操作结果:用e返回L中第i个数据元素的值 */
 66     if(i<1||i>L.length)
 67       exit(ERROR);
 68      e=L.elem[i-1];//返回第i个数据 
 69      return OK;
 70 }
 71 
 72 Status compare(ElemType c1,ElemType c2) /* 数据元素判定函数(平方关系) */
 73 {
 74    if(c1==c2*c2)
 75      return TRUE;
 76    else
 77      return FALSE;
 78 }
 79 
 80 int LocateElem(SqList L,ElemType e,Status(*compare)(ElemType,ElemType))
 81 {
 82 /* 初始条件:顺序线性表L已存在,compare()是数据元素判定函数(满足为1,否则为0) */
 83 /* 操作结果:返回L中第1个与e满足关系compare()的数据元素的位序。 */
 84 /*           若这样的数据元素不存在,则返回值为0。算法2.6 */
 85   ElemType *p;
 86   int i=1;
 87   p=L.elem;
 88   while(i<=L.length&&!(*compare)(*p++,e))
 89    ++i;
 90    if(i<=L.length)
 91      return i;
 92     else
 93      return 0;    
 94 } 
 95 Status PriorElem(SqList L,ElemType cur_e,ElemType &pre_e)
 96  { 
 97 /* 初始条件:顺序线性表L已存在 */
 98 /* 操作结果:若cur_e是L的数据元素,且不是第一个,则用pre_e返回它的前驱, */
 99 /*           否则操作失败,pre_e无定义 */
100    int i=2;
101    ElemType *p=L.elem+1;
102    while(i<=L.length&&*p!=cur_e)
103    {
104      p++;
105      i++;
106    }
107    if(i>L.length)
108      return INFEASIBLE;
109    else
110    {
111      pre_e=*--p;
112      return OK;
113    }
114  }
115 
116 Status NextElem(SqList L,ElemType cur_e,ElemType &next_e)
117  { 
118 /* 初始条件:顺序线性表L已存在 */
119 /* 操作结果:若cur_e是L的数据元素,且不是最后一个,则用next_e返回它的后继, */
120 /*           否则操作失败,next_e无定义 */
121    int i=1;
122    ElemType *p=L.elem;
123    while(i<L.length&&*p!=cur_e)
124    {
125      i++;
126      p++;
127    }
128    if(i==L.length)
129      return INFEASIBLE;
130    else
131    {
132      next_e=*++p;
133      return OK;
134    }
135  }
136 
137 Status ListInsert(SqList &L,int i,ElemType e) /* 算法2.4 */
138  { 
139 /* 初始条件:顺序线性表L已存在,1≤i≤ListLength(L)+1 */
140 /* 操作结果:在L中第i个位置之前插入新的数据元素e,L的长度加1 */
141    ElemType *newbase,*q,*p;
142    if(i<1||i>L.length+1) /* i值不合法 */
143      return ERROR;
144    if(L.length>=L.listsize) /* 当前存储空间已满,增加分配 */
145    {
146      newbase=(ElemType *)realloc(L.elem,(L.listsize+LISTINCREMENT)*sizeof(ElemType));
147      if(!newbase)
148        exit(OVERFLOW); /* 存储分配失败 */
149      L.elem=newbase; /* 新基址 */
150      L.listsize+=LISTINCREMENT; /* 增加存储容量 */
151    }
152    q=&(L.elem[i-1]); /* q为插入位置 */
153    for(p=&(L.elem[i-1]);p>=q;--p) /* 插入位置及之后的元素右移 */
154      *(p+1)=*p;
155    *q=e; /* 插入e */
156    ++L.length; /* 表长增1 */
157    return OK;
158  }
159 
160  Status ListDelete(SqList &L,int i,ElemType &e) 
161  { 
162 /* 初始条件:顺序线性表L已存在,1≤i≤ListLength(L) */
163 /* 操作结果:删除L的第i个数据元素,并用e返回其值,L的长度减1 */
164    ElemType *p,*q;
165    if(i<1||i>L.length) /* i值不合法 */
166      return ERROR;
167    p=&L.elem[i-1]; /* p为被删除元素的位置 */
168    e=*p; /* 被删除元素的值赋给e */
169    q=L.elem+L.length-1; /* 表尾元素的位置 */
170    for(++p;p<=q;++p) /* 被删除元素之后的元素左移 */
171      *(p-1)=*p;
172    --L.length; /* 表长减1 */
173    return OK;
174  }
175  
176 void visit(ElemType *c) /* ListTraverse()调用的函数(类型要一致) */
177 {
178    printf("%d ",*c);
179 }
180 
181 void dbl(ElemType *c) /* ListTraverse()调用的另一函数(元素值加倍) */
182 {
183    *c*=2;
184 }
185  Status ListTraverse(SqList L,void(*visit)(ElemType*))
186  { 
187 /* 初始条件:顺序线性表L已存在 */
188 /* 操作结果:依次对L的每个数据元素调用函数vi()。一旦vi()失败,则操作失败 */
189 /*           vi()的形参加'&',表明可通过调用vi()改变元素的值 */
190    ElemType *p;
191    int i;
192    p=L.elem;
193    for(i=1;i<=L.length;i++)
194      visit(p++);
195    printf("\n");
196    return OK;
197  }
198 Status equal(ElemType c1,ElemType c2)
199 { 
200 /* 判断是否相等的函数,Union()用到 */
201    if(c1==c2)
202      return TRUE;
203    else
204      return FALSE;
205 }
206 
207 void Union(SqList &La,SqList Lb) /* 算法2.1 */
208 { 
209 /* 将所有在线性表Lb中但不在La中的数据元素插入到La中 */
210    ElemType e;
211    int La_len,Lb_len;
212    int i;
213    La_len=ListLength(La); /* 求线性表的长度 */
214    Lb_len=ListLength(Lb);
215    for(i=1;i<=Lb_len;i++)
216    {
217      GetElem(Lb,i,e); /* 取Lb中第i个数据元素赋给e */
218      if(!LocateElem(La,e,equal)) /* La中不存在和e相同的元素,则插入之 */
219        ListInsert(La,++La_len,e);
220    }
221 }
222 
223 void MergeList(SqList La,SqList Lb,SqList &Lc) /* 算法2.2 */
224 { 
225 /* 已知线性表La和Lb中的数据元素按值非递减排列。 */
226 /* 归并La和Lb得到新的线性表Lc,Lc的数据元素也按值非递减排列 */
227    int i=1,j=1,k=0;
228    int La_len,Lb_len;
229    ElemType ai,bj;
230    InitList(Lc); /* 创建空表Lc */
231    La_len=ListLength(La);
232    Lb_len=ListLength(Lb);
233    while(i<=La_len&&j<=Lb_len) /* 表La和表Lb均非空 */
234    {
235      GetElem(La,i,ai);
236      GetElem(Lb,j,bj);
237      if(ai<=bj)
238      {
239        ListInsert(Lc,++k,ai);
240        ++i;
241      }
242      else
243      {
244        ListInsert(Lc,++k,bj);
245        ++j;
246      }
247    }
248    while(i<=La_len) /* 表La非空且表Lb空 */
249    {
250      GetElem(La,i++,ai);
251      ListInsert(Lc,++k,ai);
252    }
253    while(j<=Lb_len) /* 表Lb非空且表La空 */
254    {
255      GetElem(Lb,j++,bj);
256      ListInsert(Lc,++k,bj);
257    }
258 }
259 
260 void MergeList_Sq(SqList La,SqList Lb,SqList &Lc) /* 算法2.7 */
261 { 
262 /* 已知顺序线性表La和Lb的元素按值非递减排列。 */
263 /* 归并La和Lb得到新的顺序线性表Lc,Lc的元素也按值非递减排列 */
264    ElemType *pa,*pa_last,*pb,*pb_last,*pc;
265    pa=La.elem;
266    pb=Lb.elem;
267    Lc.listsize=Lc.length=La.length+Lb.length;/*不用InitList()创建空表Lc */
268    pc=Lc.elem=(ElemType *)malloc(Lc.listsize*sizeof(ElemType));
269    if(!Lc.elem) /* 存储分配失败 */
270      exit(OVERFLOW);
271    pa_last=La.elem+La.length-1;
272    pb_last=Lb.elem+Lb.length-1;
273    while(pa<=pa_last&&pb<=pb_last) /* 表La和表Lb均非空 */
274    { /* 归并 */
275      if(*pa<=*pb)
276        *pc++=*pa++;
277      else
278        *pc++=*pb++;
279    }
280    while(pa<=pa_last) /* 表La非空且表Lb空 */
281      *pc++=*pa++; /* 插入La的剩余元素 */
282    while(pb<=pb_last) /* 表Lb非空且表La空 */
283      *pc++=*pb++; /* 插入Lb的剩余元素 */
284 }
View Code

       主函数

  1 void print(ElemType *c)
  2 {
  3    printf("%d ",*c);
  4 }
  5 
  6 void Sq_Main()
  7 {
  8    SqList L;
  9    ElemType e,e0;
 10    Status i;
 11    int j,k;
 12    i=InitList(L);
 13    printf("初始化L后:L.elem=%u L.length=%d L.listsize=%d\n",L.elem,L.length,L.listsize);
 14    for(j=1;j<=5;j++)
 15      i=ListInsert(L,1,j);
 16    printf("在L的表头依次插入1~5后:*L.elem=");
 17    for(j=1;j<=5;j++)
 18      printf("%d ",*(L.elem+j-1));
 19    printf("\n");
 20    printf("L.elem=%u L.length=%d L.listsize=%d\n",L.elem,L.length,L.listsize);
 21    i=ListEmpty(L);
 22    printf("L是否空:i=%d(1:是 0:否)\n",i);
 23    i=ClearList(L);
 24    printf("清空L后:L.elem=%u L.length=%d L.listsize=%d\n",L.elem,L.length,L.listsize);
 25    i=ListEmpty(L);
 26    printf("L是否空:i=%d(1:是 0:否)\n",i);
 27    for(j=1;j<=10;j++)
 28      ListInsert(L,j,j);
 29    printf("在L的表尾依次插入1~10后:*L.elem=");
 30    for(j=1;j<=10;j++)
 31      printf("%d ",L.elem[j-1]);
 32    printf("\n");
 33    printf("L.elem=%u L.length=%d L.listsize=%d\n",L.elem,L.length,L.listsize);
 34    ListInsert(L,1,0);
 35    printf("在L的表头插入0后:*L.elem=");
 36    for(j=1;j<=ListLength(L);j++) /* ListLength(L)为元素个数 */
 37      printf("%d ",L.elem[j-1]);
 38    printf("\n");
 39    printf("L.elem=%u(有可能改变) L.length=%d(改变) L.listsize=%d(改变)\n",L.elem,L.length,L.listsize);
 40    GetElem(L,5,e);
 41    printf("第5个元素的值为:%d\n",e);
 42    for(j=3;j<=4;j++)
 43    {
 44      k=LocateElem(L,j,compare);
 45      if(k)
 46        printf("第%d个元素的值为%d的平方\n",k,j);
 47      else
 48        printf("没有值为%d的平方的元素\n",j);
 49    }
 50    for(j=1;j<=2;j++) /* 测试头两个数据 */
 51    {
 52      GetElem(L,j,e0); /* 把第j个数据赋给e0 */
 53      i=PriorElem(L,e0,e); /* 求e0的前驱 */
 54      if(i==INFEASIBLE)
 55        printf("元素%d无前驱\n",e0);
 56      else
 57        printf("元素%d的前驱为:%d\n",e0,e);
 58    }
 59    for(j=ListLength(L)-1;j<=ListLength(L);j++) /* 最后两个数据 */
 60    {
 61      GetElem(L,j,e0); /* 把第j个数据赋给e0 */
 62      i=NextElem(L,e0,e); /* 求e0的后继 */
 63      if(i==INFEASIBLE)
 64        printf("元素%d无后继\n",e0);
 65      else
 66        printf("元素%d的后继为:%d\n",e0,e);
 67    }
 68    k=ListLength(L); /* k为表长 */
 69    for(j=k+1;j>=k;j--)
 70    {
 71      i=ListDelete(L,j,e); /* 删除第j个数据 */
 72      if(i==ERROR)
 73        printf("删除第%d个数据失败\n",j);
 74      else
 75        printf("删除的元素值为:%d\n",e);
 76    }
 77    printf("依次输出L的元素:");
 78    ListTraverse(L,visit); /* 依次对元素调用visit(),输出元素的值 */
 79    printf("L的元素值加倍后:");
 80    ListTraverse(L,dbl); /* 依次对元素调用dbl(),元素值乘2 */
 81    ListTraverse(L,visit);
 82    DestroyList(L);
 83    printf("销毁L后:L.elem=%u L.length=%d L.listsize=%d\n",L.elem,L.length,L.listsize);    
 84 } 
 85 
 86 void Union_Main()
 87 {
 88    SqList La,Lb;
 89    Status i;
 90    int j;
 91    i=InitList(La);
 92    if(i==1) /* 创建空表La成功 */
 93      for(j=1;j<=5;j++) /* 在表La中插入5个元素 */
 94        i=ListInsert(La,j,j);
 95    printf("La= "); /* 输出表La的内容 */
 96    ListTraverse(La,print);
 97    InitList(Lb); /* 也可不判断是否创建成功 */
 98    for(j=1;j<=5;j++) /* 在表Lb中插入5个元素 */
 99      i=ListInsert(Lb,j,2*j);
100    printf("Lb= "); /* 输出表Lb的内容 */
101    ListTraverse(Lb,print);
102    Union(La,Lb);
103    printf("new La= "); /* 输出新表La的内容 */
104    ListTraverse(La,print);
105 }
106 void MergeList_Main()
107  {
108    SqList La,Lb,Lc;
109    int j,a[4]={3,5,8,11},b[7]={2,6,8,9,11,15,20};
110    InitList(La); /* 创建空表La */
111    for(j=1;j<=4;j++) /* 在表La中插入4个元素 */
112      ListInsert(La,j,a[j-1]);
113    printf("La= "); /* 输出表La的内容 */
114    ListTraverse(La,print);
115    InitList(Lb); /* 创建空表Lb */
116    for(j=1;j<=7;j++) /* 在表Lb中插入7个元素 */
117      ListInsert(Lb,j,b[j-1]);
118    printf("Lb= "); /* 输出表Lb的内容 */
119    ListTraverse(Lb,print);
120    MergeList(La,Lb,Lc);
121    printf("Lc= "); /* 输出表Lc的内容 */
122    ListTraverse(Lc,print);
123 }
124 
125 void MergeList_Sq_Main()
126 {
127    SqList La,Lb,Lc;
128    int j;
129    InitList(La); /* 创建空表La */
130    for(j=1;j<=5;j++) /* 在表La中插入5个元素 */
131      ListInsert(La,j,j);
132    printf("La= "); /* 输出表La的内容 */
133    ListTraverse(La,print);
134    InitList(Lb); /* 创建空表Lb */
135    for(j=1;j<=5;j++) /* 在表Lb中插入5个元素 */
136      ListInsert(Lb,j,2*j);
137    printf("Lb= "); /* 输出表Lb的内容 */
138    ListTraverse(Lb,print);
139    MergeList(La,Lb,Lc);
140    printf("Lc= "); /* 输出表Lc的内容 */
141    ListTraverse(Lc,print);
142 }
143 
144 int main()
145 {
146   printf("--------------------------------------------------------------\n");
147   Sq_Main();
148   printf("--------------------------------------------------------------\n");
149   Union_Main();
150   printf("--------------------------------------------------------------\n");
151   MergeList_Main();
152   printf("--------------------------------------------------------------\n");
153   MergeList_Sq_Main();
154   return 0;
155 }
View Code

 

posted @ 2016-06-11 01:33  太过随意  阅读(447)  评论(0)    收藏  举报