线性表学习02——线性表的顺序表示和实现

目录

一、线性表的顺序表示

1.1定义

1.2顺序表中元素存储位置的计算

1.3顺序表的顺序存储表示

1.4顺序表示意图

二、顺序表中基本操作的实现

1.1线性表L的初始化

1.1.1销毁线性表L

1.1.2清空线性表

1.1.3求线性表L的长度

1.1.4判断线性表L是否为空

1.2顺序表的取值

1.3线性表的查找

1.3.1算法描述

 1.3.2算法分析

1.4线性表的插入

1.4.1插入不同位置的算法演示

1.4.2插入情况

1.4.3算法描述

1.4.4算法分析

1.5线性表的删除

1.5.1删除不同位置的算法演示

1.5.2删除情况

1.5.3算法描述

1.5.4算法分析


一、线性表的顺序表示

1.1定义

线性表的顺序表示又称为顺序存储结构或顺序映像。

顺序存储定义:把逻辑上相邻的数据元素存储在物理上相邻的存储单元中的存储结构。简言之,逻辑上(存储顺序)相邻,物理上(存放位置)也相邻

注:逻辑位序和物理位序相差1,即a1存储在数组下标为0的位置,a2存储在数组下标为1的位置。

如线性表:(a1,a2,...,a(i-1),a(i),a(i+1),...a(n))

a1a2...a(i-1)a(i)a(i+1)...a(n)

 线性表的第1个数据元素a1的存储位置,称作线性表的起始位置或基地址。

注:顺序存储结构必须是依次存储,地址连续的,即中间没有空出存储单元。这样才是一个典型的线性表顺序存储结构。所以我们知道某个元素的存储位置就可以计算其他元素的存储位置。

随机存取是顺序存储结构的优点)

如线性表(1,2,3,4,5,6)的存储结构:

123456
123456

而这样的存储结构就不是一个线性表顺序存储结构,因为它的地址是不连续的。

1.2顺序表中元素存储位置的计算

计算方法:

假设每个元素占l个存储单元,则第i+1个元素的存储位置与第i个元素的存储位置之间满足关系:

LOC(a(i+1))=LOC(a(i))+l

由此得到公式:

LOC(a(i))=LOC(a1)+(i-1)×l,LOC(a1)为基地址

例如,

①每个元素占用8个存储单元,a(i)存储位置是2000单元,则a(i+1)存储位置是(2000+8=)2008单元。

②每个元素占用8个存储单元,a1存储位置是10单元,则a6存储位置是(10+5×8=)50单元。

1.3顺序表的顺序存储表示

顺序表(元素)是依次存放、地址连续、随机存取、类型相同的,与数组(元素)一致,所以我们就用一维数组来表示顺序表。

但线性表长可变(因为可删除,插入),而数组长度不可动态定义,所以我们用一变量表示顺序表的长度属性。

#define MAXSIZE 100   //多项式可能达到的最大长度

typedef struct{

   ElemType *elem;        //存储空间的基地址

   int length;                   //当前长度

}SqList;                      //顺序表的结构类型为SqList

实例① 多项式的顺序存储结构类型定义

P(n)(x)=p1x的e1次方+p2x的e2次方+...+p(m)x的e(m)次方:

线性表P=((p1,e1),(p2,e2),...,(pm,em))

#define MAXSIZE 1000     //多项式可能达到的最大长度

typedef struct{                 //多项式非零项的定义

float p;                            //系数

int e;                               //指数

}Polynomial;

typedef struct{

Polynomial *elem            //存储空间的基地址

int length;                     //多项式中当前项的个数

}SqList;                     //多项式的顺序存储结构类型为SqList

实例② 图书表的顺序存储结构类型定义

#define MAXSIZE 10000      //图书表可能达到的最大长度

typedef struct{                    //图书信息定义

char no[20];                          //图书ISBN

char name[50];                     //图书名字

float price;                            //图书价格

}Book;

typedef struct{

Book *elem;                        //存储空间的基地址

int length;                         //图书表中当前图书个数

}SqList;                          //图书表的顺序存储结构为SqList

     

1.4顺序表示意图

我们定义了SqList类型,还需要定义变量L,这样才会对变量分配空间。

#define MAXSIZE 100

typedef struct{

ElemType *elem;

int length;

}SqList;     //定义顺序表类型

SqList L;     //定义变量L,L是SqList这种类型的,L是个顺序表。

数组元素:  L.elem[0] L.elem[1] L.elem[2] L.elem[3] L.elem[4] L.elem[5]  ...L.elem[99]

数组元素下标:       0             1              2              3              4              5   ....          99

线性表L内容:         a             b              c              d              e              f                               6

线性表的成员:     L.elem                                                                                            L.length

若L是指针,则SqList *L,线性表L成员为:L-> elem  L->length

二、顺序表中基本操作的实现

补充:操作算法中用到的预定义常量和类型

//函数结果状态代码:

#define  TRUE   1

#define  FALSE  0

#define  OK        1

#define  ERROR  0

#define  INFEASIBLE  -1

#define  OVERFLOW  -2

//Status  是函数的类型,其值是函数结果状态代码

typedef  int  Status;

typedef  char ElemType;

1.1线性表L的初始化

就是将内存空间分配出来并进行赋值

(参数用引用)

Status InitList_Sq(SqList &L){                                //构造一个空的顺序表L

     L.elem=new ElemType[MAXSIZE];                     //为顺序表分配空间

     if(!L.elem) exit(OVERFLOW);                             //存储分配失败

     L.length=0;                                                         //空表长度为0

     return OK;

补充几个基本操作

1.1.1销毁线性表L

void DestroyList(SqList &L){

      if (L.elem) delete  L.elem;                //释放存储空间

}

1.1.2清空线性表

void ClearList(SqList &L){

      L.length=0;                                   //将线性表的长度置为0

}

1.1.3求线性表L的长度

int GetLength(SqList L){

     return(L.length);

1.1.4判断线性表L是否为空

int IsEmpty(SqList L){

    if(L.length==0)  return 1;

    else return 0;

1.2顺序表的取值

(根据位置i获取相应位置数据元素的内容 ——>随机存取)

算法描述:

int GetElem(SqList L,int i, ElemType &e){

     if(i<1 || i>L.length)  return ERROR;      //判断i值是否合理,若不合理,返回ERROR

     e=L.elem[i-1];                                       //第i-1个的单元存储着第i个数据

     return OK;

}

1.3线性表的查找

(在线性表L中查找与指定值e相同的数据元素的位置)

1.3.1算法描述

int LocateElem(SqList L,ElemType e){    

//在线性表L中查找值为e的数据元素,返回其序号(是第几个元素)

    for(i=0;i<L.length;i++)(0<=i<=n-1 表示下标)

         if (L.elem[i]==e) return i+1;     //查找成功,返回序号(序号比下标多1)

    return 0;                                      //查找失败,返回0

}

 1.3.2算法分析

①基本操作:L.elem[i]==e (将记录的关键词同给定值进行比较)

如线性表 a,b,c,d,e,f,g...

②比较次数:e=a,1次;e=b,2次;e=c,3次;.......,e=g,7次;

所以平均查找长度(ASL)为:(1+2+3+4+5+6+7)/7=4

ASL=Pi·Ci求和

=P1+2P2+3P3....+(n-1)P(n-1)+nPn

=(1/n)(1+2+...+n)

=(n+1)/2

Pi是第i个记录被查找的概率(1/n),Ci是找到第i个记录需比较的次数

④平均时间复杂度为O(n)

1.4线性表的插入

1.4.1插入不同位置的算法演示

有线性表1,2,3,4,5

·插入位置在最后——直接把元素插在最后一个位置

123456

 ·插入位置在中间——插入元素的后面元素依次往后移

123645

·插入位置在最前面——插入前的所有元素均依次往后移

612345

1.4.2插入情况

·插入后,线性表长度+1;

·插入位置在0~n范围(下标)

·假设所有元素都占据了空间,那么再插入的话就造成了溢出。

1.4.3算法描述

Status ListInsert_Sq(SqList &L,int i,ElemType e){

①if(i<1 || i>L.length+1)  return ERROR;           //i值不合法

②if(L.length==MAXSIZE) return ERROR;       //当前存储空间已满

for(j=L.length-1;j>=i-1;j--)                             //j表示下标,i表示第几个元素,即元素序号

        L.elem[j+1]=L.elem[j];                             //插入位置及之后的元素后移

④L.elem[i-1]=e;                                             //将新元素e放入第i个位置

⑤L.length ++;                                                //表长增1

   return OK;

}

1.4.4算法分析

①算法时间主要耗费在移动元素的操作上

·若插入在尾结点之后,则根本无需移动(快)

·若插入在首结点之前,则表中元素全部后移(慢)

·若考虑在各种位置上插入,则共有n+1种可能

E(ins)=Pi·(n-i+1)求和

=(1/(n+1))·求和(n-i+1)

=(1/(n+1))(n+n-1+n-2+...+1+0)

=n/2

Pi是表示在任何位置上插入元素的概率:1/(n+1);  (n-i+1)表示移动的次数

③平均时间复杂度为O(n)

1.5线性表的删除

1.5.1删除不同位置的算法演示

有线性表1,2,3,4,5

·删除位置在最后

12345(删除)

·删除位置在中间

1234(删除)5

1235

·删除位置在最前面

1(删除)2345

2345

1.5.2删除情况

·删除后,线性表长度-1

·删除位置是0~n-1范围(下标)

1.5.3算法描述

Status ListDelete_Sq(SqList &L,int i){

①       if((i<1) || i>L.length)) return ERROR;       //i值不合法

②       for (j=i;j<=L.length-1;j++)

          L.elem[j-1]=L.elem[j];                               //被删除元素之后的元素前移

③      L.length--;                                                //表长-1

         return OK;

}

1.5.4算法分析

①算法时间主要耗费在移动元素的操作上

·若删除尾结点,则无需移动(快)

·若删除首结点,则表中n-1个元素全部前移(慢)

·若考虑在各种位置删除(共n种可能)

E(del)=Pi·(n-i)求和

(1/n)·(n-i)求和

=(1/n)·(n(n-1)/2)

=(n-1)/2

Pi表示在任何位置上删除的概率都是1/n, (n-i)表示移动的次数

③平均时间复杂度为O(n)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值