#include<stdio.h>
#include<malloc.h>
#include<stdlib.h> //包含了exit函数
//1.第一步我们先定义一个指针结构体 ( 结构体只是定义了一个数据类型)
struct Arr
{
int * pBase; //该指针用来存储数组第一个元素的地址
int len; //数组能够容纳的最大元素的个数
int cnt; //当前数组有效元素的个数
};
//2.声明需要实现的功能:
void init_arr(struct Arr * , int ); //初始化
bool append_arr(struct Arr * pArr, int val); //追加
bool insert_arr(struct Arr * pArr, int pos, int val); //插入 (pos的值从1开始)
bool delete_arr(struct Arr * pArr, int pos, int * pVal); //删除
bool get_arr(struct Arr *, int ,int *); //获取值
bool is_empty(struct Arr *); //判断是否空
bool is_full(struct Arr *); //判断是否满
void sort_arr(struct Arr * pArr); //排序
void show_arr(struct Arr *); //显示
void inversion_arr(struct Arr * pArr); //倒置
int main(void)
{
struct Arr arr; //3.定义一个struct Arr类型变量
//4.我们只是定义完这个结构体以后,该结构体内的元素还需要进行初始化
//(否则里面存储的是垃圾数据)
int val;
int get;
int position;
init_arr(&arr,6); //5.初始化
// printf("%d\n", arr.len); //用来测试init_arr函数
show_arr(&arr); //9.显示该数组
append_arr(&arr,1); //15.追加数组元素
append_arr(&arr,2);
append_arr(&arr,3);
append_arr(&arr,4);
if( delete_arr(&arr,2,&val) ) //19.删除数组元素
{
printf("删除成功!\n");
printf("您删除的元素是:%d\n",val);
}
else
{
printf("删除失败!\n");
}
inversion_arr(&arr); //倒置数组元素
/* append_arr(&arr,2);
append_arr(&arr,3);
append_arr(&arr,4);
append_arr(&arr,5);
insert_arr(&arr,6,99); //18.检验插入函数
/* append_arr(&arr,6);
append_arr(&arr,7);
append_arr(&arr,8); //16.这里因为追加元素超出我们初始化的数组长度6,无法显示
if (append_arr(&arr,8))
{
printf("追加成功\n");
}
else
{
printf("追加失败\n");
}*/
printf("倒置之后的数组内容是:\n");
show_arr(&arr);
printf("排序之后的数组内容是:\n");
sort_arr(&arr); //排序函数
show_arr(&arr);
printf("请输入你要查找的是第几个元素:"); //查找
scanf("%d",&position);
if( get_arr(&arr,position,&get) )
{
printf("查找到数组中的第%d个元素值为:%d\n", position, get);
}
else
{
printf("查找失败!\n");
}
return 0;
}
void init_arr(struct Arr * pArr, int length) //6.初始化函数的实现
//这里我们需要修改结构体变量的值, 所以必须要使用取地址/指针的方式来传递数据
{
pArr->pBase = (int *)malloc(sizeof(int) * length);
//7.这里我们通过动态分配内存将int *类型的第一个地址传递给 pArr->pBase指针
//8.这里要注意的是如果内存分配不成功,比如系统内存满了,malloc函数会将NULL赋给指针
//系统规定NULL(全0地址)无法访问和修改
if(NULL == pArr->pBase)
{
printf("动态内存分配失败!\n");
exit(-1); //表示非正常终止程序运行
}
else
{
pArr->len = length;
pArr->cnt = 0;
}
return; //表示函数终止
}
void show_arr(struct Arr * pArr) //10.显示函数的实现
{
if(is_empty(pArr)) //11.这里我们需要判断数组是否为空,先去完成is_empty函数
{
printf("数组为空!\n");
}
else
{
for(int i=0; i<pArr->cnt; ++i)
printf("%d ",pArr->pBase[i]);
//这里pArr是指向结构体的,我们要指向数组内容的话,需要通过pArr->pBase这个指针来指向数组的首地址
printf("\n");
}
}
bool is_empty(struct Arr * pArr) //12.is_empty函数的实现
{
if(pArr->cnt == 0)
return true;
else
return false;
}
bool is_full(struct Arr * pArr) //13.is_full函数的实现
{
if (pArr->cnt == pArr->len)
return true;
else
return false;
}
bool append_arr(struct Arr * pArr, int val) //14.追加函数的实现
{
//满时返回false
if(is_full(pArr))
return false;
//不满时追加
pArr->pBase[pArr->cnt] = val;
(pArr->cnt)++;
/*
pArr->pBase这个指针是指向数组的第一个地址,等价于数组名
后面[pArr->cnt]为下标:cnt为当前有效元素的个数,
因为有效元素的个数是包含零的,所以这里cnt的值实际上比最后一个有效的下标高上一位
因此可以直接作为下一个要赋值的数组元素的下标
*/
}
bool insert_arr(struct Arr * pArr, int pos, int val) //17.插入函数的实现
{
if(is_full(pArr))//; //如果满则返回错误
return false; //这里这个分号是我出的错,敲了直接结束了if语句,
//然后不管怎么样都会直接执行return false;语句直接跳出函数
if(pos<1 || pos>pArr->cnt+1) //位置不合法返回错误,cnt+1为当前有效值的后一位(即在所有元素最后一个位置插入)
return false;
//先将要插入元素的位置以及其后面的值集体后移1位,为插入值腾出位置
//注意这里我们必须从最后一位开始右移(为了避免数值的覆盖)
for (int i=pArr->cnt-1; i>=pos-1; i--)
{
pArr->pBase[i+1] = pArr->pBase[i]; //最后一个值赋给它后面的一个空间
}
pArr->pBase[pos-1] = val;
pArr->cnt++;
return true;
}
bool delete_arr(struct Arr * pArr, int pos, int * pVal) //20.删除函数的实现
{
if( is_empty(pArr) )
return false;
if(pos<1 || pos>pArr->cnt) //删除的时候就不能删所有元素的后面一位了
return false;
*pVal = pArr->pBase[pos-1]; //将所要删除的值赋给主函数中val变量所在的地址中
for (int i=pos; i<pArr->cnt; i++)
{
pArr->pBase[i-1] = pArr->pBase[i];
//这里直接将要删除的那一位后面的元素全部前移一位 (覆盖掉要删除的值)
}
pArr->cnt--;
return true;
}
void inversion_arr(struct Arr * pArr) //21.倒置函数的实现
{
int i = 0;
int j = pArr->cnt-1;
int temp;
while (i < j)
{
temp = pArr->pBase[i];
pArr->pBase[i] = pArr->pBase[j];
pArr->pBase[j] = temp;
i++;
j--;
}
return;
}
void sort_arr(struct Arr * pArr)
{
int temp;
for (int i=0; i<pArr->cnt; ++i)
{
for(int j=i+1; j<pArr->cnt; ++j)
{
if(pArr->pBase[i] > pArr->pBase[j])
{
temp = pArr->pBase[i];
pArr->pBase[i] = pArr->pBase[j];
pArr->pBase[j] = temp;
}
}
}
return;
}
bool get_arr(struct Arr * pArr, int pos,int *pVal)
{
if( is_empty(pArr) )
return false;
if(pos<1 || pos>pArr->len)
return false;
*pVal = pArr->pBase[pos-1];
return true;
}
数据结构自学——(2)链表的代码实现
最新推荐文章于 2024-09-11 02:01:15 发布
本文详细介绍了如何使用C语言来实现链表数据结构,包括链表的基本操作,如创建、插入、删除节点等,适合自学数据结构的读者参考。
摘要由CSDN通过智能技术生成