数据结构之线性表

来源:互联网 发布:诸暨市行知小学介绍 编辑:程序博客网 时间:2024/06/06 08:28

一、线性表的概念和定义

1、线性表的逻辑结构特点

线性表是一种最简单的线性结构,是一个数据元素的有序(次序)集。

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

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

除最后元素之外,每个元素均有唯一的后继;

除第一元素之外,每个元素均有唯一的前驱;

2、线性表的基本术语

线性表可描述为n(n≥0)个具有相同特性的数据元素组成的有限序列。

常表示为:L={a1 ,…, ai-1, ai, ai+1, …, an};ai必须具有相同特性,即属于同一数据对象。

ai-1是ai的直接前驱元素,ai+1是ai的直接后继元素;

数据元素ai在线性表中有确定的位置i,i称为位序;

线性表中数据元素的个数n称为线性表的长度,n=0时,线性表称为空表。

3、ADT定义

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

GetElem(L,i,&e)

初始条件:

      线性表L已存在,且1<=i<=LengthList(L).

操作结果:

     用e返回L中第i个元素的值。

LocateElem(L,e,compare())

初始条件:

       线性表L已存在,e为给定值,compare()是元素判定函数。

操作结果:

      返回L中第一个与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.

二、线性表的顺序存储实现——顺序表

1.顺序存储(映像)方式

          以x的存储位置和y的存储位置之间某种关系表示逻辑关系<x,y>.最简单的一种顺序映像方法是:令y的存储位置和x的存储位置相邻。

2.顺序表的C语言描述

          #define  List_INIT_SIZE 100   //线性表存储空间的初始分配容量

typedef struct

{

      ElemType *elem; //存放线性表的数组空间基地址

      int   length;    //当前长度(实际元素个数)

      int   listsize;  //当前分配的容量

}SqlList;//称 顺序表

顺序表的基本形态

定义:sqList L;

空表

L.length==0 可插入不可删除

表满

L.length>=L.listsize 可删除不可插入(空间再分配)

表不空不满

0<L.lenth<L.listsize  可删除可插入

3、线性表的基本操作在顺序表中的实现

初始化:

       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;

        }//InitList_Sq

int Locate(SqList L,ElemType e)

{  //在顺序表L中查询第一个等于e的数据元素,若存在,则返回它的位序,否则返回0

i=1;           //i的初值为第1元素的位序

for(i<=L.length;i++)

     if(L.elem[i-1]==e)

         return i;

return 0;

}//Locate

Status  search_i(SqList L,int i,ElemType &e)

{//在顺序表L中查找第i个元素,若存在用e返回其值并返回OK,否则返回ERROR

      if(i>0&&i<=L.length)

      {

             e=L.elem[i-1];

              return OK;

      }

else

       return ERROR;

}

线性表的插入操作(ListInsert(&L,i,e))的实现:

分析:

插入元素时,线性表的逻辑结构发生了什么变化?

(a1,...,ai-1,ai,...,an)改变为(a1,...,ai-1,e,ai,...,an)

<ai-1,ai>——><ai-1,e>,<e,ai>
需考虑的问题(步骤)
1.当前表是否已满?
2.输入(插入位置)是否有效?
3.插入元素

Status  ListInsert(SqList &L,int i,ElemType e)
{//在顺序表L的第i个元素之前插入新的元素e,i的合法范围为1<=i<=L.length+1
if(i<1||i>L.length+1)   return ERROR;
if(L.length>=L.listsize)
{//空间再分配
       newbase=(ElemType*)realloc(L.elem,(L.listsize+LISTINCREMENT)*sizeof(ElemType));
        if(!newbase) exit(OVERFLOW);
        L.elem=newbase;//基地址更新
        L.listsize+=LISTINCREMENT;//表容量更新
}
        for(j=L.length;j>=i;j--)
        L.elem[j]=L.elem[j-1];//插入位置及之后的元素右移
        L.elem[i-1]=e;//插入e
        ++L.length;//表长+1
         return OK;     
}//ListInsert_Sq

线性表操作
       ListDelete(&L,i,&e)的实现:
分析:
删除元素时,线性表的逻辑结构发生了什么变化?
(a1,a2,...,ai,ai+1,...,an)改变为(a1,a2,...,ai-1,ai+1,...an)
<ai-1,ai>,<ai,ai+1>——><ai-1,ai+1>
存储空间(顺序表)的变化:表的长度减少
Status  ListDelete_Sq(SqList &L,int i,ElemType &e)
{//在顺序表L中删除第i个元素,以引用参数e返回其值,若删除成功返回ok;否则返回ERROR
      if(i<1||i>L.length)
      return ERROR;//i的值不合法
      e=L.elem[i-1];
      for(j=i;j<L.length;j++)
      L.elem[j-1]=L.elem[j];//元素前移
      --L.length;
       return OK;
}//ListDelete_Sq
顺序表操作的效率分析
时间效率分析:
       算法时间主要耗费在移动元素的操作上,而移动元素的个数取决于插入或删除元素的位置。
以插入为例分析
       若插入在尾元素之后,则根本无需移动(特别快);
       若插入在首元素之前,则表中元素全部要后移(特别慢);
Status Del_k(SqList&L,int i,int k)
{//在顺序表L中删除自第i个开始的k个元素,操作成功返回ok,否则返回error;
     if(i>L.length||k>L.length-i+1)
      return ERROR;
      for(j=i+k-1;j<=L.length-1;j++)
      L.elem[j-k]=L.elem[j];//元素前移完成删除
      L.Length-=k;//顺序表长度减k
      return OK;
}
小结——顺序表的特点:
优点:可以随机存取表中任一元素,方便快捷;
缺点:在插入或删除某一元素时,需要移动大量元素;需要预先确定数据元素的最大个数。
解决问题的思路:改用另一种线性存储方式:链式存储结构。

0 0
原创粉丝点击