介绍: 本篇内容只分享数据结构和算法中最初级的内容,创建数组以及其配套的一些API,答主也是新手,水平有限,看看就好。如果想了解写C语言的环境,答主后面会补上。希望能保持一周一更的状态,后面的内容陆续会有链表,队列,栈,树以及图等数据结的创建和相关操作。
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
#include <stdbool.h>
struct Arr //创建一个结构体,结构体即为一整个数组。
{
int * pBase; //创建创建结构体里的指针变量,可以用该变量的下标找到数组的元素
int cnt; //代表数组的有效个数
int len; //代表数组的长度
};
bool is_fulled(struct Arr * pArray) //判断数组是否已经装满了数据,后面会有需要
{
if (pArray->cnt==pArray->len) //如果数组的有效个数与数组长度相等,则数组必定已经装满数据
{
return true;
}
else
{
return false;
}
}
bool append_arr(struct Arr * pArray,int val) //这是数组的一个追加方法,可以为数组最前面的空数据位置追加数据
{
if(is_fulled(pArray)) //调用了if_full方法,如果数组已满则终止程序
{
printf("数组已满,无法添加\n");
exit(-1);
return false;
}
else
{
pArray->pBase[pArray->cnt]=val; //用数据有效数据的个数作为下表,则添加数据的位置必然是空数据
pArray->cnt++; //有效数据个数加1
printf("%s%d%s","追加成功\n,有效数据为",pArray->cnt,"个\n");
return true;
}
}
void init_arr (struct Arr *pArray,int length) //这是初始化数组方法
{
pArray->len = length; //数组的长度由入参决定,并且把该长度赋予结构体的长度变量
pArray->pBase =(int *)malloc(sizeof(int) * length); //用动态分配内存的方法把大小为int类型乘以数组长度的内存,以int类型划分,并且把每份内存的首个内存地址赋值给该结构体的内存地址变量 PS:int类型为4个字节
if (NULL == pArray->pBase) //如果该结构体的内存地址变量为空,则内存必然分配失败,程序退出
{
printf("内存不足\n");
exit(-1);
}
else
{
pArray ->len = length; //如果成功,则数组长度为变更
pArray ->cnt = 0;
}
return 0;
}
bool is_empty(struct Arr * pArray) //这是判断数组是否为空的函数,为其他方法服务
{
if(pArray ->cnt == 0)
{
return true;
}
else
{
return false;
}
}
void show_arr(struct Arr * pArray) //这是展现数据所有数据的函数
{
if(is_empty(pArray)) //首先判断是否为空
printf("数组为空\n");
else
for(int i=0;i<pArray->cnt;++i){ //不为空则用遍历的方式把每个数据打印出来
if(pArray->pBase[i] != "\0")
{
printf("%d ",pArray->pBase[i]);
}
else
{
printf("Null ");
};
};
printf("\n");
}
bool insert_arr(struct Arr * pArray,int index,int val) //这是在数组中插入数据的函数,实现思路是,把插入下标右边的所有数据(包括下标本身)全部往右边移动一位,再把插入数据赋予该下标
{
if (is_fulled(pArray)==false && -1 <index < pArray->cnt) //首先需要判断数组是否已满,还需要判断下标是否为负数或者比数组的有效个数还大,增加方法的健壮性
{
for(int i=pArray->cnt;i!=index-1;--i) //将数据往右移动
{
pArray->pBase[i] = pArray->pBase[i-1];
}
pArray->pBase[index] = val; //将数据赋予该下标
pArray->cnt++; //数组有效数据加1
printf("插入成功\n");
return true;
}
else
{
printf("插入失败");
return false;
}
}
bool delete_arr(struct Arr * pArray,int index) //删除函数,需要数组内存地址,和下标两个参数
{
if (is_empty(pArray)) //判断数据是否为空
{
printf("数组为空,删除失败\n");
return false;
}
if (pArray->cnt<index ) //判断有效个数是否比需要删除的下标还小
{
printf("目标数据错误,删除失败\n");
return false;
}
int val = pArray->pBase[index]; //用一个变量将即将删除的下标保存起来,方便打印
for(int i=index;i<pArray->cnt;++i) //将下标后面的值(不包括下标该数据)全部往前移动一格
{
pArray->pBase[i]=pArray->pBase[i+1];
}
pArray->cnt--;
printf("删除成功!值为%d\n",val); //打印已经删除的数据
return true;
}
void inversion_arr(struct Arr * pArray) //这是使数组前后反转的函数
{
int val;
int index = pArray->cnt-1; //将数组最后一个有效数据的下标赋值给一个变量
for(int i=0;i<index;++i) //将第一个数据和最后一个数据交换,可以使用val这个临时变量辅助,在左边的下标大于或者等于最后的数据下标时(即重叠或者即将超过的那一次交换)停止循环
{
val =pArray->pBase[i];
pArray->pBase[i]=pArray->pBase[index];
pArray->pBase[index]=val;
index--;
}
printf("数组成功反转!\n");
}
void sort_arr(struct Arr *pArray) //对数组进行排序,其实就是一个冒泡,你们可以添加入参,可以调控排序从大到小还是从小到大,我就不写了。
{
for(int i =0 ;i<pArray->cnt;++i)
{
for (int p =0; p < pArray->cnt-i-1; ++p)
{
if(pArray->pBase[p]>pArray->pBase[p+1])
{
int val = pArray->pBase[p];
pArray->pBase[p]=pArray->pBase[p+1];
pArray->pBase[p+1]=val;
}
}
}
printf("排序成功!\n");
}
int main(void) //在main方法里调用上面的方法,调式已经看最后结果,你们可以任意使用和补充
{
struct Arr arr;
int length=6;
init_arr(&arr,length);
show_arr(&arr);
append_arr(&arr,1);
append_arr(&arr,2);
append_arr(&arr,3);
append_arr(&arr,4);
append_arr(&arr,5);
show_arr(&arr);
insert_arr(&arr,1,99);
show_arr(&arr);
delete_arr(&arr,2);
show_arr(&arr);
inversion_arr(&arr);
show_arr(&arr);
sort_arr(&arr);
show_arr(&arr);
}
各位有什么补充以及建议都可以评论给我,欢迎大家交流想法。
|