飞鸟各投林

导航

第1天线性表顺序存储

线性表是一种最简单的线性结构

线性结构的基本特征为:线性结构是一个数据元素的有序(次序)集

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

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

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

4.除第一元素之外,均有 唯一的前驱

线性表:n个数据元素组成的有限序列。表示为(a1,a2,…,ai,ai+1,…,an)

一:线性表的顺序存储方式

线性表的顺序存储方式定义为:用一组地址连续的存储单元依次存放线性表中的数据元素以“存储位置相邻”表示有序对<ai-1,ai>

线性表的起始地址称作线性表的基地址

 即:LOC(ai) = LOC(ai-1) + C

       LOC(ai) = LOC(a1) + (i-1)×C

所有数据元素的存储位置均取决于第一个数据元素的存储位置

 

线性表的表示方法:

 1 #define  LIST_INIT_SIZE   80 // 线性表存储空间的初始分配量
 3 #define  LISTINCREMENT    10 // 线性表存储空间的分配增量 
 5 typedef  struct { 
 7    ElemType *elem;         // 存储空间基址
 9    int      length;        // 当前长度
11    int     listsize;       // 当前分配的存储容量,(以sizeof(ElemType)为单位)
13 } SqList;               // 俗称 顺序表

 

算法1:合并线性表(利用已有的函数实现)

假设:有两个集合 A 和 B 分别用两个线性表 LA 和 LB 表示,即:线性表中的数据元素即为集合中的成员。

现要求一个新的集合A=A∪B。上述问题可演绎为:要求对线性表作如下操作:

扩大线性表 LA,将存在于线性表LB 中而不存在于线性表 LA 中的数据元素插入到线性表 LA 中去。

操作步骤:

  1. 从线性表LB中依次察看每个数据元素;

 GetElem(LB, i)→e

  1. 依值在线性表LA中进行查访;

LocateElem(LA, e, equal( ))

  1. 若不存在,则插入之。

ListInsert(LA, n+1, e)

例:  LA=(8,5,11,3)

LB=(6,8,2,9,20,15,11)

则:   LA=(8,5,11,3,6,2,9,20,15}

代码实现:

 1 void union(List &La, List Lb) {
 3       La_len = ListLength(La);    // 求线性表的长度 
 5       Lb_len = ListLength(Lb);    
 7       for (i = 1; i <= Lb_len;  i++) {
 9       GetElem(Lb, i, e); // 取Lb中第i个数据元素赋给e 
11       if (!LocateElem(La, e, equal( )) ) 
13        ListInsert(La, ++La_len, e); // La中不存在和 e 相同的数据元素,则插入之 
15                } 
17 } 

 

 

算法2:合并有序表,用已知函数实现

有序表:若线性表中的数据元素依值非递减或非递增有序排列,

即 aiai-1 或 aiai-1(i = 2,3,, n),则称该线性表为有序表。

比如:1,3,5,6,8,10,20,23

 

已知线性表La和Lb中的数据元素按值非递减有序排列,现要求La和Lb归并为一个新的线性表Lc,且Lc中的数据元素仍按值非递减有序排列

实现步骤:

1.分别从La和Lb中取得当前元素ai和bj;

2.若ai≤bj,则将ai插入到Lc中,否则将bj插入到Lc中。

例:  La=(3,5,8,11)

        Lb=(2,6,8,9,11,15,20)

则:     Lc=(2,3,5,6,8,8,9,11,11,15,20}

代码实现:

 1  void MergeList(List La, List Lb, List &Lc) // 本算法将非递减的有序表 La 和 Lb 归并为 Lc 
 3 {
 5     initList(Lc);  // 构造空的线性表 Lc
 7     i = j = 1;    k = 0;
 9     La_len = ListLength(La);
11     Lb_len = ListLength(Lb);
13     while ((i <= La_len) && (j <= Lb_len))  
15         { GetElem(La, i, ai);     
17           GetElem(Lb, j, bj);
19         if (ai <= bj) { ListInsert(Lc, ++k, ai);  ++i; }// 将 ai 插入到 Lc 中
21         else { ListInsert(Lc, ++k, bj);  ++j; }// 将 bj 插入到 Lc 中
23         }
25     while (i<=La_len) // 当La不空时
27         { GetElem(La, i++, ai);   ListInsert(Lc, ++k, ai);} // 插入 La 表中剩余元素
29     while (j<=Lb_len)  // 当Lb不空时
31         { GetElem(Lb, j++, bj);  ListInsert(Lc, ++k, bj); } // 插入 Lb 表中剩余元素
32 
33 } 

 


算法3:直接实现有序表的合并操作,不用已知函数。

 1 void MergeList(List La, List Lb, List &Lc) {
 5     pa=La.elem;  pb=Lb.elem;
 9     Lc.listsize=Lc.length=La.length+Lb.length;  //Lc的长度赋值
13     Pc=Lc.elem=(elemtype *)malloc(Lc.listsize*sizeof(elemtype));
17     If(!Lc.elem)  exit(overflow); //给Lc动态分配存储空间
21     pa_last = La.elem+La.length-1; //记录La的最后元素存放位置
25     pb_last = Lb.elem+Lb.length-1 ; //记录Lb的最后元素存放位置
29     while (pa <= pa_last) && (pb<= pb_last) 
33      {  if(*pa<=*pb)  *pc++=*pa++;
37         eles *pc++=*pb++;}//归并操作
41     while (pa <= pa_last) *pc++=*pa++;  // 若 La 不空
45     while (pb<= pb_last)  *pc++=*pb++;  // 若 Lb 不空
49 }  


算法4:线性表的结构初始化

 1 Status InitList_Sq( SqList& L ) {
 5     L.elem = (ElemType*) malloc (LIST_INIT_SIZEsizeof (ElemType));
 9     if (!L.elem) exit(OVERFLOW);
13     L.length = 0;
17     L.listsize = LIST_INIT_SIZE;
21     return OK;
25 } // InitList_Sq算法时间复杂度:O(1)
26 
27  

 

算法5:输出线性表内容

 1 Void Printlist( SqList L ) {
 5     int i;
 9     printf("\n*********************");
13     printf("\nThe element of the sqlist are:\n");
17     for(i=0;i<L.length;i++)
21     printf("%d    ",L.elem[i]);
25     printf("\n*********************\n");
29     return;
33 }//算法时间复杂度:O(L.length)

 

算法6:线性表的插入元素

 1 Status ListInsert_Sq(SqList &L, int i, ElemType e)
 3  {   // 在顺序表L的第 i 个元素之前插入新的元素e,
 5     // i 的合法范围为  1≤i≤L.length+1
 7 if (i < 1 || i > L.length+1) return ERROR// 插入位置不合法
 9 if (L.length >= L.listsize) 
13     { // 当前存储空间已满,增加分配
17     newbase = (ElemType *)realloc(L.elem, (L.listsize+LISTINCREMENT)*sizeof (ElemType));                                                           
19     if (!newbase) exit(OVERFLOW);  // 存储分配失败
23     L.elem = newbase;           // 新基址
27     L.listsize += LISTINCREMENT;  // 增加存储容量     
31     }
35     q = &(L.elem[i-1]); // q 指示插入位置
37     for (p = &(L.elem[L.length-1]); p >= q;  ---p)  // p表尾元素的位置
39     *(p+1) = *p;   // 插入位置及之后的元素右移
41     *q = e;       // 插入e
43     ++L.length;   // 表长增1
45     return OK;
47 } // ListInsert_Sq  算法时间复杂度为: O( ListLength(L) )
 
 
算法7:线性表的删除元素
 3 Status ListDelete_Sq (SqList &L, int i, ElemType &e) { 
 5         if ((i < 1) || (i > L.length))  return ERROR; // 删除位置不合法
 7         p = &(L.elem[i-1]);       // p 为被删除元素的位置
 9         e = *p;                   // 被删除元素的值赋给 e
11         q = L.elem+L.length-1;    // 表尾元素的位置
13         for (++p; p <= q; ++p)  
15         *(p-1) = *p;  // 被删除元素之后的元素左移
17         --L.length;   // 表长减1 
19         return OK;
21 } // ListDelete_Sq
 
 

顺序存储结构的优缺点:

优点:

1:逻辑相邻,物理相邻:

2:可随机存取任一元素

3:存储空间使用紧凑

缺点::

1插入、删除操作需要移动大量的元素

2:预先分配空间需按最大空间分配,利用不充分:

3:表容量难以扩充

  1 附:代码参考
  3 #define list_size 15
  5 #define increment 5 
  7 #define ok    1 
  9 #define overflow -1 
 11 #define error -2 
 13 #include "stdlib.h" 
 15 #include "stdio.h"
 17 typedef struct{ int *elem; 
 19 int length; 
 21 int listsize;}sqlist;
 23 int initlist(sqlist *L) 
 25 { L->elem=(int *)malloc(list_size*sizeof(int));
 27   if(!L->elem) exit(overflow); 
 29   L->length=0;
 31   L->listsize=list_size;
 33   return ok;  }
 35 int listinsert( sqlist *L,  int i,  int e )
 37 { int *p,*q,*newbase;
 39 if(i<1||i>L->length+1) return error; 
 41 if(L->length>=L->listsize) 
 43 {newbase=(int *)realloc(L->elem,(L->listsize+increment)*sizeof(int)); 
 45  if(!newbase)exit(overflow); 
 47  L->listsize+=increment;}
 49  q=&(L->elem[i-1]);
 51  for(p=&(L->elem[L->length-1]);p>=q;--p) *(p+1)=*p;   *q=e;   ++L->length;
 53  return ok;}
 55 void printlist(sqlist *L) 
 57 {int i; 
 59 printf("\n*********************"); 
 61 printf("\nThe element of the sqlist are:\n");
 63 for(i=0;i<L->length;i++) 
 65 printf("%d    ",L->elem[i]);
 67 printf("\n*********************\n");
 69 return;
 71 }
 73 main(   )
 75 {  int i,j,e;
 77   sqlist L1; 
 79   initlist(&L1);
 81   printf(“\n Please insert the length of the sqlist:\n"); 
 83   scanf("%d",&L1.length);
 85   printf(“\n Please insert the element of the sqlist:\n");
 87   for(i=0; i<L1.length; i++)
 89   scanf( “%d”, &L1.elem[ i ]);
 91   printlist(&L1);
 93   printf("\nPlease insert the value of j ane e :\n"); 
 95   scanf("%d%d",&j,&e); 
 97   listinsert(&L1, j, e);
 99   printlist(&L1);  
101 }

 

 

posted on 2016-04-11 15:48  飞鸟各投林  阅读(339)  评论(0编辑  收藏  举报