二.插入数据函数实现(重点)
我们先来看数据要怎么插入,如下图是一个顺序表结构:
顺序表长度为10,下标0~9,每个格子里都有数据,但其length值为5,所以只有前5个数据15677为有效数据。(左端连续的情况下)
现在要往2号位置插入数据,值为100
那么这里pos位置就是2号位置(下标为2),val值就是100,
那我们的操作就是让2号位置的6变为100,步骤如下
1.先把从2号位置往后的数据都往后移动,那怎么挪
我们可以看到红色竖线是最后一个有效数字的界线,那我们的移动就要从最后一个有效数字开始移动,将4号位置的7往后挪一位,直接覆盖掉5号位置的无效数字8,然后4号位置就空了,依次将3号位置7移到4号,2号6移到3号。此时2号位置就空了,可以将val值100插入到2号位置了。插入完成后有效数据长度就要改为6.
那么这里我们就先需要定义一个 i 指向下标,利用下标来判断和移动位置。
此时我们的下标i指向最后一位有效数据,然后将 i 的值赋值给 i+1 的值,即i+1==i;
然后移动下标位置向前一位(i的值是length-1,下标=长度-1)
一直移动到pos位置,pos位置的值也需要往后挪,所以循环在i=pos的那一步也要执行(循环条件的分界线(<,>,=,<=,>=)要判断好)
接下来完成代码
这样写看似是完成了,其实代码还存在一个问题------我们并没有判断哪些位置能插入,哪些位置不能插入。这个叫------参数判断,一般写在一进入函数的开始。参数判断也是要把每个数据成员都考虑一遍,例如这个插入函数的3个参数。PS要看是否为空(前面也说过PS是从外面传进来的,你也不知道每个使用者都是什么想法,如果就有人传一个空的进来,为了保证代码的算法的健壮性,就要进行参数判断);pos要看位置是否能插入;而val在这里就没有什么限制,则可以不判断。所以这有2个参数要判断。
所以插入函数的总代码如下
//判断表是否满,用静态函数来写
static bool IsFul(PSQList PS)
{
return PS->length == 10;//有效数据长度==表长 即满了。相当于下面的一个if else
//if (PS->length == 10)
//return true;//表满
//else
//return false;//不满
}
//插入数据,在顺序表PS的pos位置插入val数据元素
//插入操作有2种结果,插入成功或失败,所以其插入函数原型是bool类型,只返回2种结果
bool Insert(PSQList PS, int pos, int val)//参数就是实现这个函数的使用需要外界提供给它的数据东西
{
//参数判断
assert(PS != NULL);//第一个参数
if (PS == NULL)
return false;
if (pos<0||pos > PS->length||IsFul(PS))
//pos位置是下标,0号位置即表头可以插入。
//pos==length即在表尾(length-1)后面新加一个
//PS放满了也不插入,这里判断表满的函数写在该插入函数上面
{
return false;//插入不了
}
//把数据移动到后面
for (int i = PS->length - 1; i >= pos; i--)//指向符访问length和elem成员
{
PS->elem[i + 1] = PS->elem[i];
}
//插入数据
PS->elem[pos] = val;
//有效数据个数++
PS->length++;
//是bool类型,都完成后return true
return true;
}
现在来检查测试一下插入函数(在text里面)
首先这样写有错但程序并没有崩溃
而它之所以没有显示输出我们插入的函数对不对,是我们没有写输出函数Show
三.输出函数
//要养成一进入函数先参数判断的习惯
这里再说一点,我们调用printf函数时,如果报错一般情况下是要引用头文件#include<stdio.h>。
这就跟我们现在写的(.h)和(.cpp)的多文件同理,stdio.h文件里放了printf输出函数的定义与声明,那就应该有一个类似于stdio.cpp的文件(不一定叫stdio.cpp这个名字)存放写这个printf函数的功能实现, 而我们这个(.cpp)文件里就是在调用,使用printf这个函数,所以只用引用其头文件,不用管其怎么具体实现的。 因为输出printf函数经常且广泛使用,所以C语言把它和其他一些类型的函数都写到了C语言的库函数里面,也就是说以后你只要使用printf函数,直接引用其头文件就好,不用再像我们平时自己写其他自定义函数一样去写函数的原型和实现,也就是不用关心printf其函数底层是怎么实现的。函数的原型和实现C语言库里就有,别人已经帮你写好了,这样做目的就是更方便。
接下来给插入函数的测试加上Show再输出就是这样
其功能是在 i 号位置 插入 数字 i 数据,表长为10,所以只插入了0~9共10个数字。
虽然循环是从-1一路走到19,但因为这是定长顺序表,长度固定为10,且程序也没有崩溃。
有时候我们测试只单纯随便测个2号或3号位置就走了,而我们测试最主要的就是要全面,各个边界点和内部随机点都要测到。 例如这里我们可能就会遗漏-1点。