线性表:顺序表,链表,栈,队列,字符串
线性表在逻辑上是线性结构,也就是说连续的一条直线,但是在物理结构上并不一定是连续的。线性表在物理上存储时,通常以数组和链式结构的形式存储。
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;
}