您的位置:首页 > 理论基础 > 数据结构算法

数据结构---线性表----顺序存储结构

2016-03-18 14:12 260 查看
1.线性表定义
        线性表(LIST):零个或多个数据元素的有限序列。
   关键知识点:
        1.首先它是一个序列,元素之间室友顺序的;
        2.线性表强调的是有限的,元素个数是有限的;
        3.在较复杂的线性表中,一个数据元素可以由若干个数据项组成。
        其数学定义:
        若将线性表标记为(a1, …,ai-1,
ai, ai+1,
…, an),则表中的ai-1领先于ai,ai领先 于ai+1
 ,称ai-1是ai的直接前驱元素。 ai+1是ai的直接后继元素。
       线性元素的个数n(n>=0)定义为线性表的长度,当n=0时称为空表。
       线性表知识框架

2.线性表的抽象数据类型
ADT 线性表

Data
线性表的数据对象集合为(a1, …,ai-1, ai, ai+1, …, an),每个元素的类型均为DateType。其中,除了第一个元素a1外,每一个元素都有且只有一个直接前驱元素,除了最后一个元素外,每一个元素都有且只有一个直接后继元素。数据元素之间的关系是一对一的关系。

Operation
InitList(*L);                  初始化操作,建立一个空的线性表L;
ListEmpty(L);                 若线性表L为空,返回True, 否则返回False;
ClearList(*L);                  清空线性表;
GetElem(L, i, *e);        将线性表L中的第i个位置的元素值返回给e;
LocateElem(L, e);            在线性表L中查找与e相等的元素,如果查找成功,返回该元素
在表中的序号表示成功,否则返回0表示失败;
ListInsert(*L, i, e);           在线性表L的第i个位置插入新元e;
ListDelete(*L, i, *e);        删除线性表L中第i个位置的元素,并返回e;
ListLength(L);                 返回线性表L的元素个数;

endADT


3.线性表的顺序存储结构
       顺序存储定义:
            线性表的顺序存储结构,指的是用一段地址连续的存储单元依次存储线性表的数据元素。 
        线性表顺序存储的结构代码:
#define MAXSIZE 20          /*存储空间的初始分配数量*/
typedef int Elemtype;       /*ElemType 类型根据实际情况定*/
typeof struct
{
ElemType data[MAXSIZE ];     /*数组存储数据元素,最大值为MAXSIZE*/
int length;                               /*线性表的当前长度*/
}SqList;


        注意  数据长度与线性表长度的区别        
    数据长度是指存储线性表的存储空间的长度,存储分配后这个是一般不会改变的。
    线性表的长度是线性表中元素的个数,随着线性表的插入和删除操作而变化。
    在任意时刻,线性表的长度应该小于等于数组的长度、

         地址计算方法:
         假设每个元素占用C个存储单元,那么线性表中第i个元素的存储位置与i+1 个数据元素的的存储位置的关系:
         LOC --- 获得存储位置的函数                   
          LOC(ai+1 )
= LOC(ai)+ C

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


4.顺序存储结构的插入与 删除

   线性表获得元素的操作 
GetElem(L, i, *e)

<strong>  </strong>    #define  OK  1
#define  ERROR  0
#define  TRUE   1
#define  FALSE 0
typedef int Status ;
/*Status 是函数的类型,其值是函数结果的状态代码, 如OK 等*/
/*初始条件:顺序线性表L已经存在,1=<i<= ListLength(L)*/
/*操作结果用e返回L中的第i个数据元素的值*/
Status  GetElem(SqlList L, int i,  Elemtype *e)
{
if (L.length == 0 ||  i<1 || i > L.length)
return  ERROR;
*e = L.data[i-1];
return OK;
}<strong>
</strong>


   
插入操作 ListInsert(*L, i, e);

 
 算法描述:

 
    1. 如果插入位置不合理,抛出异常;

 
    2. 如果线性表长度大于数组长度,则抛出异常或者动态添加容量;

 
    3. 从最后一个元素开始向前遍历到第i个位置,分别将他们向后移动一个位置;

 
    4. 将要插如的元素填入到位置I处;

 
    5. 表长加1.

具体实现代码:
 
   
/*初始条件:顺序线性表已经存在,1=<i<= ListLength(L)*/
/*操作结果在L的第i个位置插入新元素e,L的长度加1*/
Status  ListInsert(SqlList* L, int i, Elemtype e)
{
int k ;
if (L->length == MAXSIZE)             /*顺序线性表已经满*/
return ERROR;
if (i<1 || i> L->length+1)                 /*i不在范围内*/
return ERROR;
if (i<L->length)
{
for (k =L->length-1;k>=i-1;k--)
L->data[k+1]= L->data[k];
}

L->data[i-1] = e;
L->length++;
return OK;
}


       删除操作  ListDelete(*L,
i, *e);

 
     算法描述

 
        1. 如果删除位置不合理,抛出异常;
 
        2. 取出删除的元素;
 
        3. 从删除元素开始向前遍历到最后一个元素,分别将他们向前移动一个位置;
 
        4. 表长减1.
具体实现代码:
 
 
/*初始条件:顺序线性表已经存在,1=<i<= ListLength(L)*/
/*操作结果:删除L的第i个位置的数据元素e,并返回其值e,L的长度减1*/
Status  ListDelete(SqlList* L, int i, Elemtype e)
{
int k; 
if (L -> length == 0)/*线性表为空*/
return ERROR;

if (i<1 || i> L->length)                 /*i不在范围内*/
return ERROR;
*e = L->length
if (i<L->length)
{
for (k =i;k<L->length;k++)
L->data[k-1]= L->data[k];
}

L->length++ ;
return OK;
}

插入和删除的时间复杂度:由于元素插入到第i个位置,或者删除第i个元素,需要移动n-i个元素。根据概率原理,每个位置插入或者删除元素的可能性是一样的。也就是说最终的平均移动次数和最中间那个元素的移动次数相等。都是(n-1)/2.因此平均时间复杂度为O(n)。
这表明:线性表的顺序存储结构,在存储数据时,不管那个位置时间复杂度都是O(1),而在插入和删除时,时间复杂度为O(n),说明它比较适合在元素个数不太变化,而更多是存取数据的应用。

线性表顺序存储结构的优缺点:
 优点:
1.无须为表示表中元素之间的逻辑观念而增加额外的存储空间。
             
      2.可以快速地存取表中任意位置的元素。
 缺点:
1. 插入和删除操作需要移动大量的元素。 
                2. 当线性表长度变化较大时,难以确定存储空间的容量。
                3.造成空间的“碎片”。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: