数据结构之线性表的顺序存储结构(静态)

  1. 定义:用一组地址连续的存储单元依次存储线性表中的每一个数据元素,这种存储结构称为线性表的顺序存储结构,用这种结构表示的线性表称为顺序表
    顺序表的特点是用数据元素在计算机内物理位置相邻来表示线性表中数据元素之间的逻辑关系。即线性表中数据元素之间的前驱、后继关系映射到数据元素在存储单元地址的相邻关系上。可见,逻辑关系相邻的两个数据元素在物理位置上也相邻。

  2. 根据顺序表的特点可知,在C语言中可以用数组来表示顺序表。由于我们计数都是从1开始,而C语言中的数组下表是从0开始,于是线性表中的第i个数据元素αi 的存储在数组下标为i-1的位置,即数据元素的序号和存放它的数组下标之间存在对应关系
    C0AA3AC2A5DDCF12D9F829D38A751C79.png

    线性表中的第i个数据元素αi 的存储地址为:
    LOC(αi) = LOC(α1)+(i-1) * c
    其中LOC(α1)为线性表第一个数据元素的存储位置,称为线性表的首地址或基地址;c为线性表中每个数据元素占用的存储单元数。通过这个公式,可以随时算出线性表中任意位置的地址,不管它是第一个还是最后一个。

  3. 具体代码

    1. 线性表的顺序存储的结构代码
      #define MAXSIZE 20
      typedef int ElemType;
      typedef struct
      {
      	ElemType data[MAXSIZE];
      	int length;
      }Sqlist;
      /*
      *存储空间的起始位置:数组data,它的存储位置就是存储空间的存储位置.
      *线性表的最大存储容量:数组长度MAXSIZE.
      *线性表当前的长度:length.
      */
      
    2. 线性表的基本操作
      1. 初始化顺序表
        初始化顺序表就是构造一个空的顺序表,只需要把表长置为0即可
      #define OK 1
      #define ERROR 0
      typedef int Status;
      Status InitList(Sqlist *L)
      {
      	L->length = 0;
      	return OK;
      }
      
      1. 求顺序表中当前元素个数
        求顺序表当前元素个数就是求表长,而表长可以从顺序表的length域得到,因此只需输出length的值即可
      int ListLength(Sqlist L)
      {
      	return L.length;
      }
      
      1. 判断顺序表是否为空
        判断是否是空表,只需判断表长是否为0。若为0,则是空表,返回1,若不为0,则不是空表,返回0。
      int ListEmpty(Sqlist L)
      {
      	if(L.length <= 0)
      	{
      		return 1;
      	}
      	else
      	{ 
      		return 0;
      	}
      }
      
      1. 获得顺序表中的元素
        对于线性表中的顺序存储结构来讲,如果我们要实现GetElem操作,即将线性表L中的第i个位置元素值返回。就程序而言,只要i的数值在数组下标范围内,就是把数组第i-1下标的值返回即可。
      /*初始条件:顺序表L已存在,1<= i <=ListLength(L) */
      /*操作结果:用e返回L中第i个数据元素的值,注意i是指位置,第1个位置的元素的数组下标是从0开始*/
      Status GetElem(Sqlist L, int i,ElemType *e)
      {
      	if(L.length <= 0 || i < 1|| i>L.length)
      	{
      		//线性表为空或者i位置不合理
      		return ERROR;
      	}
      	*e = L.data[i-1];
      	return OK;
      }
      
      1. 遍历顺序表
        访问线性表L中的每一个元素,并且每个元素只访问一次
      void TraverseList(Sqlist L)
      {
      	int i;
      	for(i = 0;i<L.length;i++)
      	{
      		printf("%d ",L.data[i]);
      	}
      	printf("\n");
      }
      
      1. 查找指定元素在顺序表中的位置
        对于给定的数据元素,如果在顺序表中能够找到与之相同的数据元素,则返回其在顺序表中的位置。如果顺序表中有多个与之相同的数据元素,则只返回首次找到的数据元素的位置,如果没有找到与之相同的数据元素,则返回ERROR。
      int FindElem(Sqlist L,ElemType e)
      {
      	int pos= 0;
      	//判断是否是空表,如果是,直接返回ERROR
      	if(L.length <= 0)
      	{
      		return ERROR;
      	}
      	while(pos<L.length && L.data[pos]!=e)
      	{
      		pos++;
      	}
      	if(pos < L.length)
      	{
      		return pos+1;
      	}
      	else
      		return ERROR;
      }
      
      1. 向顺序表中插入数据元素
        一般情况下,在第i(1<=i<=ListLength(L))个元素之前插入一个数据元素时,需要将第n至第i个元素依次后移一个位置,插入后顺序表的长度为n+1。
        插入图示:
        3107F02EAE9CD6ED2F87F97C15611006.png
        操作步骤如下:
        • 判断所给顺序表是否已存满数据元素,若满则产生上溢出错误;
        • 检查插入位置是否合法,即==“1<=i<=ListLength(L)+1”==条件是否满足;
        • 将顺序表的第i个元素到最后一个元素之间的所有元素依次向后移动一个位置,为新元素空出插入位置,并且应该从顺序表的最后一个元素开始移动;
        • 将要插入元素填入位置i处;
        • 表长加1;
      Status ListInsert(Sqlist *L,int i,ElemType e)
      {
      	int k;
      	if(L->length >= MAXSIZE)
      		return ERROR;
      	if(i < 1 || i>L->length+1)
      		return ERROR;
      	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;
      }
      
      1. 删除顺序表中的元素
        一般情况下,删除第i(1<=i<=ListLength(L))个元素,需要将第i+1至最后一个元素依次前移一个位置,删除后顺序表的长度为ListLength(L)-1
        删除图示:
        516E6B0823B25E94C244E615460B3C91.png
        操作步骤如下:
        • 判断所给顺序表是否为空,若空则产生下溢错误;
        • 检查删除位置是否合法,即==“1<=i<=ListLength(L)”==条件是否满足
        • 将顺序表的第i+1个元素到最后一个元素之间的所有元素依次向前移动一个位置。并且应该从顺序表的第i+1个元素开始移动;
        • 顺序表长度减1
      Status ListDelete(Sqlist *L,int i,EleType *e)
      {
      	int k;
      	if(L->length == 0)
      		return ERROR;
      	if (i < 1|| i > L->length)
      		return ERROR;
      	*e = L->data[i-1];
      	for (k = i;k<L->length;k++)
      	{
      		L->data[k-1] = L->data[k];
      	}
      	L->length--;
      	return OK;
      }
      
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值