线性表的顺序存储表示和实现

线性表的顺序表示和实现

线性表有两种基本的存储结构:顺序存储结构,链式存储结构;

顺序存储

顺序存储:把逻辑上相邻的数据元素存储在物理上相邻的存储单元中的存储结构。(中间没有空出存储单元,连续)
线性表第一个数据元素a1的存储位置,称为线性表的起始位置或基地址。
假设线性表的每个元素需占l个存储单元,则第i+1个数据元素的
存储位置和第i个数据元素的存储位置之间满足关系:LOC(ai+1)=LOC(ai)+l;
所有数据元素的存储位置均可由第一个数据元素的存储位置得到:
LOC(ai)=LOC(a1)+(i-1)*l;//LOC(a1):基地址
顺序表的特点:

  1. 以物理位置相邻表示逻辑关系;
  2. 任意元素可随机存取。
  3. 顺序表(元素){地址连续,依次存放,随机存取,类型相同}数组(元素)=>一维数组表示顺序表
  4. 线性表长可变(删除/插入): 用一变量表述顺序表的长度属性,数组长度不可动态定义
#define LIST_INIT_SIZE 100 //线性表存储空间的初始分配量
typedef struct{
ElemType elem[LIST_INIT_SIZE];
int length;//当前长度 
}SqList;
例:
#define MAXSIZE 1000//多项式可能达到的最大程度
typedef struct{//多项式非零项的定义
   float p;//系数
   int e;//指数
}Polynomial;
typedef struct{
polynomial *elem;//存储空间的基地址
int length;//多项式中当前项的个数
}SqList;//多项式的顺序存储结构类型为SqList

线性表的顺序存储表示
逻辑位序和物理位序相差1;

顺序表示意图:

typedef struct{
ElemType elem[LIST_INIT_SIZE];
int length;//当前长度 
}SqList;//定义顺序表类型,不分配空间;
SqList L;//定义变量L,L是SqList这种类型的,L是个顺序表
L.elem;L->elem;

函数结果状态代码:

#define TRUE         1;
#define TALSE         0;
#define OK           1;
#define ERROR        0;
#define INFEFLOW     -1;
#define OVERFLOW    -2;
//Status  是函数的类型,其值是函数结果状态代码
typedef int Status;
typedef char ElemType;

线性表的应用:

线性表的初始化(参数用引用):
Status InitList Sq(SqList &L){//构造一个空的顺序表L
L.elem=new ElemType[MAXSIZE];//为顺序表分配空间
if(!L.elem)  exit(OVERFLOW);//存储分配失败
L.length=0;//空表长度为零
return OK;
}
销毁线性表L:
void DestroyList (SqList &L){
   If(L.elem) delete L.elem;//释放存储空间
}
清空线性表L:
void ClearList (SqList &L){
L.length=0;//将线性表的长度置为0
} 
求线性表的长度:
int GetLength(SqList L){
return (L.length);
}
判断线性表是否为空:
int IsEmpty(SqList L){
   if(L.length==0) return 1;
   else return 0;
}

顺序表的取值:(根据位置i获取相应位置数据元素的内容
int GetElem (SqList l,int i,ElemType &e){
   if(i<1|i>L.length) return ERROR;//判断i值是否合理,若不合理,返回ERROR
   e=L.length[i-1];//第i-1的单元存储着第i个数据
   return OK;
}

顺序表的查找方式:(按值查找)

在线性表L中查找与指定值e相同的数据元素的位置,从表的一端开始开始,逐个进行记录的关键字和给定值的比较。找到,返回该元素的位置序号,未找到,返回0。

int LocatedElem(SqList L,ElemType e){
//在线性表L中查找值为e的数据元素,返回其序号(是第几个元素)
   for(i=0;i<L.length;i++)
      if (L.length[i]==e) return i+1;//查找成功,返回序号
   return 0;//查找失败,返回0
}  

平均查找长度:ASL=(1/n)*(1+2+…+n)=(n+1)/2;//每个记录的查找概率相等
顺序表的插入:(下标在0~n之间)
1.判断插入位置i是否合法;
2.判断顺序表的存储空间是否已满,若已满返回ERROR;
3.将第n至第i位的元素依次向后移动一个位置,空出第i个位置。
4.将要插入的新元素e放入第i个位置。
插入位置在最后;
插入位置在中间;
插入位置在最前面。
代码如下:

Status SqListInsert_Sq(SqList &l,int i,ElemType e){//时间复杂度:O(n)
   if(i<1||i<L.length+1) return ERROR;//i值不合法,i代表的是1插入的位置,不是下标
   If(L.length==MAXSIZE) return ERROR;//当前存储空间已满
   for(j=L.length-1;j>=i-1;j--)
L.elem[j+1]=L.elem[j];//插入位置及之后的元素后移
   L.elem[i-1]=e;//将新元素e放入第i个位置
   L.length++;//表长增1
   return OK;
}

顺序表的删除算法:

删除位置在最后:
删除位置在中间:
删除位置在最前面:
算法思想:O(n)
1.判断删除位置i是否合法(合法值为1<=i<=n);
2.将欲删除的元素保留在e中;
3.将第i+1至第n位的元素一次向前移动一个位置;
4.表长减一,删除成功返回OK。

Status ListDelete_Sq(SqList&L,int i){
   if((i<1)||(i>L.length)) return ERROR;//不合法
   for(j=i;j<=L.length-1;j++)
L.elem[j-1]=L.elem[j];//被删除元素之后的元素前移
   L.length--;//表长减一
return OK;
}

顺序表总结:

优点:
1.存储密度大(结点本身所占存储量/结点结构所占存储量)
2.可以随机存取表中任一元素
缺点:
1.在插入/删除某一元素时,需要移动大量元素
2.浪费存储空间
3.属于静态存储形式,数据元素的个数不能自由扩充

你可能感兴趣的:(笔记,#,数据结构及算法基础)