数据结构---顺序表

本文详细介绍了顺序表(数组)和链表的实现,包括动态扩容策略、头尾插入与删除操作,以及如何处理边界条件,如内存不足和访问越界。通过实例代码演示了如何编写和调试线性表相关功能,并提供了测试用例以确保正确性。
摘要由CSDN通过智能技术生成

线性表:顺序表,链表,栈,队列,字符串

线性表在逻辑上是线性结构,也就是说连续的一条直线,但是在物理结构上并不一定是连续的。线性表在物理上存储时,通常以数组和链式结构的形式存储。


2.我们所指的顺序表一般指数组。数组有静态和动态之分。

首先我们理解下顺序表的实质上 数据管理。联系实际我们以两个角度思考这个代码的实现。时间和空间。时间上来讲,根据作用时间的不同,分成短时效和长时效。长时效来看我们要建立一套存储逻辑,短时效来看我们要建立若干操作逻辑。除了基本逻辑和介绍的知识点外,程序的调试也作为一大板块。修订程序要有几点把握:测试  边界(无穷小,无穷大)。


存储逻辑:创建数组和我们的构想方法

//静态数组创建,只有存储逻辑
#define N 1000
typedof double SLDataType;
typedof struct SeqList
{  SLDataType a[N];
    int size;
}SL
//动态数组创建
typedof double SLDataType;
typedof struct SeqLIist
{   SLDataType*  a;
    int size;
    int capacity;



void SeqListInit(SL* ps);
void SeqListPushBack(SL* ps, SLDataType x);
void SeqListPopBack(SL* ps);
void SeqListPushFront(SL* ps, SLDataType x);
void SeqListPopFront(SL* ps, SLDataType x);

说明:

1.typedof的应用有利于我们后面修改变量类型。宏定义的定义方式也便于静态数组后期的修改。

2.SL*在动态数组中的使用:

操作逻辑:增删改查

说明;

1. 【增】基本逻辑  size++

头插和尾插。头插指顺序表的头空间=一个运输容器,通过头插向数组输送刚插入的项。所以逻辑上只能是不断将其他项向后移,以保证头部空间是free,这就意味着一定会有一个操作是将后移,然后不断地清除头空间使之释放待插入。

//尾插
void SeqListPushBack(SL* ps,SLDataType x)
{
 if(ps->size==ps->capacity)//扩容条件判定
    {int new capacity=ps->capacity==0?4:ps->capacity*2;
     SLDataType*  tmp=(SlDataType*)realloc(ps->a,newcapacity*sizeof(SLDataType));
     if(tmp==NULL)//原数组为空
      {
         printf("realloc fail\n");
         exit(-1);
       }
         ps->a=tmp;
         ps->capacity=newcapacity;
     }
}


//头插
void SeqListPushFront(SL* ps,SLDataType x)
{
   int end=ps->size-1;
while(end>=0)
{
ps->a[end+1]=ps->a[end];
--end;
}
ps->a[0]=x;
ps->size++;
}

测试:右边界 无穷大----解决内存不够--->扩容(操作)---->设置扩容条件检验

           左边界0----初始化斟酌(逻辑)

  2.关于realloc,特点原地直接扩,若异地扩则要开辟新地址,将原数据拷贝,再一起移回原地址。

举一反三

2【减】size--  (这里介绍头删和尾删)

右边界安全,左边界--->0--->负无穷

//尾删
void SeqListPopBack(SL* ps)
{
  if(ps->size>0)
{ps->a[ps->size-1]=0;
ps->size--;
}



//头删
void SeqListFrontBack(SL* ps)
{assert(ps->size>0);
int begin=1;
while(begin<ps->size)
{
ps->a[begin[-1]=ps->a[begin];
ps->size--;
}
}

问题实质:设置条件使循环阻断在0,不越左边界

两种方式:(1)常见的if语句来判断逻辑,作用:不执行被限制条件的代码,相当于跳过问题代码

(2)断言,勿忘在SeqList.c中添加头文件 #include<assert.h>。作用:由限制条件

    防越界条件限制代码;

//条件不满足则不执行
if(ps->size>0)
{ ps->a[ps->size-1]=0;
  ps->size--;
}

//断言,为假则终止程序
{assert(ps->size>0);
ps->size--;
}

程序修订与调试

程序的修订也是一个程序员进修的重要的板块。

逻辑方面:新建专门的test.c测试区。独立且清晰的分区便于我们梳理思路和管理。 

操作方面:有循序渐进的测试思路(建议写一段测一段)

加深理解:打开断点测试工具,常用监视功能,F9打断点后,再按F10按步调试。对                      于本题需关注size和capacity个数的变化。建议尝试。

测试区代码部分示例:

#include "SeqList.h"
void TextSeqList1()//尾插测试
{SL sl;
SeqListInit(&sl);
SeqListPushBack(&sl,1);
SeqListPushBack(&sl,2);
SeqListPushBack(&sl,3);
SeqListPushBack(&sl,4);
SeqListPushBack(&sl,5);
SeqListPrint(&sl);
SeqlistDestroy(&sl);
}

void TextSeqList2()//头删测试
{SL sl;
SeqListInit(&sl);
SeqListPopFront(&sl);
SeqListPopFront(&sl);
SeqListPopFront(&sl);
}

int main()//测试总开关
{
  TextSeqList1();//测试分开关
  TextSeqList2();
  return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

刘敬_

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

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

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

打赏作者

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

抵扣说明:

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

余额充值