首先我们知道为数组分配的空间是连续的。
接下来我们利用结构体,以及一些用户自定义函数进行对一维数组的简单实现。
首先我们要明确创建一个一维数组需要确定哪几个元素。下面给出了答案:
typedef struct Array
{
int * pBase; //数组名,即是数组首个元素的地址
int cnt; //数组有效元素个数
int len; //数组的长度
}ARRAY, * PARRAY;
只需要数组首个元素的地址,有效元素个数,以及数组的长度就可以确定一个一维数组;
接着我们来实现对数组的初始化操作。我们对一个函数封装实现该功能。
void inti_array(PARRY pArr,int length)
{
pArr-pBase = (int *)malloc(sizeof(int) * length); //动态为数组分配空间,分配length个大小为int的空间
pArr->cnt = 0; //有效元素为0个
pArr->len = length; //自定义数组长度
return; //结束函数
}
然后我们再实现两个比较简单的功能,判断数组是否空和是否满。
bool is_empty(PARRAY pArr)
{
if(0 == pArr->cnt) //当数组的有效元素为零时即为空
return true;
else
return false;
}
bool is_full(PARRAY pArr)
{
if(pArr->len == pArr->cnt) //同理当数组有效元素等于数组长度时即为满
return true;
else
return false;
}
接下来实现为数组追加元素
bool append_array(PARRY pArr, int val)
{
if(is_empty(pArr))
return false;
pArr->pBase[pArr->cnt] = val; //将追加的值赋给数组元素
(pArr->cnt)++; //追加成功后有效元素加一
return true;
}
然后实现在原数组中插入一个元素
首先我们写出一个这样的函数的整体框架
bool insert_array(PARRAY pArr, int pos, int val)//数组首元素的地址,插入元素的位置,插入的元素
{
}
接着内部应该如何去写。
首先应该判断要进行操作的数组是否已满,如果已满则无法进行插入
if(is_full(pArr)) //调用前面封装的is_full()函数
return false;
接着判断插入位置参数pos是否有意义
if(pos > pArr->cnt + 1 || pos < 1) //因为是在pos前插入,如果pos小于1,或者比有效元素大二,
return false; //则无法插入
接下来要实现元素的插入,我们先谈谈他的伪算法,先把要插入元素的位置的后面的元素整体往后移动(因为数组是连续的,不能像链表一样直接插入)。空出的位置留给要插入的元素。
因为需要将元素不断的后移,所以我们需要一个循环结构来实现。我们先完成 一个循环的整体框架:
for(i = (pArr->cnt) - 1; i >= pos-1; i--)
{
}
在for循环的内部就很容易去写了
pArr->pBase[i+1] = pArr->pBase[i];
接着在for循环外部将元素插入
pArr->pBase[pos-1] = val; //将要插入元素的值val赋给空出来的元素
(pArr->cnt)++; //插入了一个元素,则有效元素加一
这样插入函数的实现就完成了
下面看整个函数封装的代码:
bool insert_array(PARRAY pArr, int pos, int val)
{
int i;
//判断数组是否已满
if(is_full(pArr))
return false;
//判断pos的值是否有意义
if(pos > (pArr->cnt) + 1 || pos < 1)
return false;
//将pos后的数组整体后移
for(i = (pArr->cnt) - 1; i >= pos-1; i--)
{
pArr-pBase[i+1] = pArr->pBase[i];
}
//插入val
pArr->pBase[pos-1] = val;
(pArr->cnt)++;
return true;
}
接着我们实现数组元素的删除功能,并将删除的元素返回给主函数。
我们依旧先写一个函数的基本框架:
bool delete_array(PARRAY pArr, int pos, int * pVal)
{
}
然后写他的内部
首先应该判断数组是否为空
if(is_empty(pArr))
return false;
在进行删除操作前,我们要把即将删除的元素返回给主函数
*pVal = pArr->pBase[pos-1];
接着要实现删除,我们先谈谈伪算法。很简单,直接把要删除位置的后面整体前移一位即可。
连续前移所以我们依旧要使用循环结构
先写出循环结构的基本框架
for(i = pos-1; i < (pArr->cnt)-1; i++)
{
}
再写内部
pArr->pBase[i] = pArr->pBase[i+1];
接着在for循环外部
(pArr-<cnt)--;
这样我们就完成了删除函数,下面是整个封装函数的代码
bool delete_array(PARRAY pArr, int pos, int * pVal)
{
int i;
//判断是否为空
if(is_empty(pArr))
return false;
//判断pos是否无意义
if(pos > pArr->cnt || pos < 1)
return false;
//将要删除元素的值返回给主函数
*pVal = pArr->pBase[pos-1];
//整体前移
for(i = pos-1; i < (pArr->cnt)-1; i++)
{
pArr->pBase[i] = pArr->pBase[i+1];
}
(pArr->cnt)--;
return true;
}
下面我们来实现数组元素的倒置,按照惯例先写出函数基本框架
void invert_array(PARRAY pArr)
{
}
要实现倒置我们先谈谈他的伪算法。可以将第一位和最后一位元素互换,接着将第二位和倒数第二位互换......这样我们就将整个数组倒置了。这里不断互换的过程可以用循环来实现。
while循环实现:
int i = 0;
int j = (pArr-cnt)-1;
while(i < j)
{
t = pArr->pBase[i];
pArr->pBase[i] = pArr->pBase[j];
pArr->pBase[j] = t;
i++;
j--;
}
整个函数的代码:
void invert_array(PARRAY pArr)
{
int t;
int i = 0;
int j = (pArr-cnt)-1;
while(i < j)
{
t = pArr->pBase[i];
pArr->pBase[i] = pArr->pBase[j];
pArr->pBase[j] = t;
i++;
j--;
}
return;
}