【数据结构线性表 C/C++】顺序表的操作(初始化,删除,增加,求表长,判空,查找,初始化,清空,销毁)

线性表的定义与特点
n 线性表
Ø n 个具有 相同特性 的数据元素的 有限序列
n 线性表、栈、队列、字符串和数组都属于 线性结构
n 线性结构反映结点间的逻辑关系是 1:1
Ø 相邻数据元素之间的序偶关系
Ø (a 1 , a 2 , …, a i -1 , a i ,  a i +1 ,…, a n )
n 对于非空的线性表或线性结构,其特点是:
Ø 存在唯一的一个被称作“第一个”的数据元素;
Ø 存在唯一的一个被称作“最后一个”的数据元素;
Ø 除第一个外,集合中的每个数据元素均只有一个直接前驱;
Ø 除最后一个之外,集合中每个数据元素均只有一个直接后继。
n 线性表的基本操作包括
Ø 将新元素插入第 i 个位置 , 1≤ i n +1 , 使原来的第 i i +1 n 个元素变为第 i +1 i +2 n +1 个元素。
Ø 删除第 i 个元素 , 1≤ i n , 使原来的第 i +1 i +2 n 个元素变为第 i i +1 n –1 个元素。
Ø 将新值赋予第 i 个元素 ,  1≤ i n
Ø 判断元素 e 是否在线性表中
Ø 计算线性表的长度 n
Ø 访问第 i 个元素 , 1≤ i n

遍历线性表中的所有元素。

n 线性表的抽象数据类型定义

ADT List {

数据对象: D={ai|ai∈ElemSet,i=1,2,...,n,n≥0}

数据关系: R={<ai-1,ai>|ai-1,ai∈D,i=2,...,n}

基本操作:InitList(&L)DestroyList(&L)、ClearList(&L) 、ListEmpty(L)、ListLength(L)、GetElem(L,i,&e)、LocateElem(L,e)、PriorElem(L,cur_e,&pre_e)、NextElem(L,cur_e,&next_e)、ListInsert(&L,i,e)、ListDelete(&L,i,&e)、TraverseList (L)

}ADT List

2.4.1 线性表的顺序存储表示
Ø 线性表的顺序存储表示 指的是用一组地址连续的存储单元依次存储线性表中的数据元素。
Ø 特点
l 逻辑上相邻的数据元素,物理上也相邻;
l 当表中首元素在存储器中的位置已知时,则可求出线性表中其他元素的存放位置。

 一个一维数组M,下标的范围是09,每个数组元素用5个字节存储。存储器按字节编址,设存储数组元素[]的第一个字节的地址是98,则M[3]的第一个字节的地址是_113___.

解:地址计算通式为:LOC(ai)  = LOC(a1) + L *i-1)因此:LOC( M3 ) = 98 + 5 ×(4-1) =113

用一维数组来表示顺序表:

typedef int ElemType;               //定义ElemType类型为int
# define  MAXSIZE   100          // 顺序表的最大长度

typedef struct {                   //若后面不再用,可省略结构名
       ElemType *elem;         //存储空间的基地址
       int    length;                  //当前表长
}SqList;                                //顺序表的类型名

线性表的顺序操作:

n 1. 初始化顺序表
Ø 对顺序表而言,“初始化”的实质是为它分配足够大的存储空间。
Ø 算法思想
l 构造一个空表,设置存储顺序表的空间大小、基地址和表长
Ø C++ 语言中,用户可以利用 new 算子向系统申请分配存储空间,该函数返回存储区的基地址。
l 示例:

int *data=new int[1000];

Status   InitList(SqList &L)
{ //构造一个空的顺序表L。
  L.elem = new ElemType[MAXSIZE];
  L.length = 0;  // 空表长度为0
  return   OK;
}

 n2.  销毁顺序

void DestroyList(SqList &L)
{
  if (L.elem) delete[ ] L.elem;    //释放存储空间
  L.length=0;
  L.elem=NULL;
}

 n3.  清空顺序

void ClearList(SqList &L) 
{
    L.length=0;   //将顺序表的长度置0
}

n4. 求顺序表的长度

int ListLength(SqList L)
{
    return L.length;             
}
n 5. 判断顺序表是否为空
bool ListEmpty(SqList L)
{
  if (L.length==0) 
     return true;      
  else
    return false;
}
bool ListEmpty(SqList L)
{
   return L.length==0;      
}
n 6.  获取顺序表中的某个数据元素内容
Status GetElem(SqList L,int i,ElemType &e)
{
  //判断i值是否合理,若不合理,返回ERROR
  if (i<1||i>L.length) return ERROR;   
  e=L.elem[i-1];   //第i-1个单元存储第i个数据
  return OK;
}

算法的时间复杂度为O(1)

n 7.  在顺序表中查找值为 e 的数据元素
int LocateElem(SqList L,ElemType e)
{
  for (i=0;i< L.length;i++)
      if (L.elem[i]==e) return i+1;                
  return 0;
}
n 8. 在顺序表中插入一个数据元素( 当在第 i 位置插入一个元素时 需要 移动 n-i+1 个元素
插入操作的算法步骤
Ø 判断 插入位置 i 是否合法,若不合法则返回 ERROR
Ø 判断顺序表的 存储空间是否已满,若满则返回 ERROR 。     
Ø 将第 n 至第 i 位的元素依次 向后移动一个位置 ,空出第 i 个位置。
Ø 将要插入的新元素 e 放入第 i 个位置
Ø 表长加 1 ,插入成功返回 OK
Status ListInsert(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--) 
       L.elem[ j+1]=L.elem[ j];   //插入位置及之后的元素后移
    L.elem[i-1]=e;                     //将新元素e放入第i个位置
   ++L.length;	//表长增1
   return OK;
}

  n9.  删除顺序表的第i个数据元素(当删除第i元素时需要移动 n-i 个元素

n 删除操作的算法步骤
Ø 判断删除位置 i 是否合法(合法值为 1≤i≤n ),若不合法则返回 ERROR
Ø 将欲删除的元素赋值给 e 。     
Ø 将第 i+1 至第 n 位的元素依次向前移动一个位置。
Ø 表长减 1 ,删除成功返回 OK
Status ListDelete(SqList &L,int i, ElemType &e){
   if(i<1||i>L.length) return ERROR;	 //i值不合法
   e=L.elem[i-1];
   for ( j=i;j<=L.length-1;j++)                   
    L.elem[ j-1 ]=L.elem[ j ]; //被删除元素之后的元素前移  
    --L.length;               	      //表长减1
   return OK;
}

 

 

由此可见,在顺序存储表示的线性表中插入或删除一个数据元素,平均约需移动表中一半元素。

顺序表的优缺点:

n 优点
Ø 可以随机存取表中任一元素 ;
Ø 无需为表示表中元素之间的逻辑关系而增加额外的存储空间;
n 缺点
Ø 在插入、删除某一元素时,需要移动大量元素;
Ø 表的容量难以确定 , 浪费存储空间

 

 

  • 4
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

beiqianqian

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值