数据结构数组接口和封装

/*********************************************************
*文件名: 动态数组.h
*创建者:ycj
*创建时间:2015-3-10
*文件说明:动态数组的增加,删除,查找,修改,排序,插入的声明
**********************************************************/


#include <stdio.h>
#include <stdlib.h>


//动态数组的属性
struct data
{
int *p;//指针保存数组的起始点
int length;//保存数组的长度
int stat;//0代表无序,1代表有序从小到大,2代表从大到小
int reallength;//实际分配的内存长度
};


//保存findalldata中数据的个数和地址
struct findres
{
int **pp;//指针保存找到的元素的地址(指针数组)
int n;//保存找到数值的个数
};


void init(struct data *pdata);//初始化


void reinit(struct data *pdata);//使用之后初始化


void addobject(struct data *pdata, int num);//增加一个数据


void addobjects(struct data *pdata, int *pnum, int n);//增加一个数组
//pnum:指向数组,n:数组元素个数


void printfall(struct data *pdata);//打印所有的数据


void sort(struct data *pdata, int flag);//排序
//obj=0;.从小到大,否则从大到小


int *finddata(struct data *pdata, int num);//查找首次出现的数据


void change(struct data *pdata, int oldnum, int newnum);//实现修改


void insert(struct data *pdata, int num, int insertnum, int headback);//数据插入
//headback:1代表前面插入,0代表后面插入,num表示插入数据位置


void deletone(struct data *pdata, int num);//删除第一个找到的数据


struct findres findalldata(struct data *pdata, int num);//找出所有的相同的数据
//返回一个结构体,包含找到元素的个数和地址

void deletall(struct data *pdata, int num);//删除所有能找到的数据




/*********************************************************
*文件名: 动态数组.c
*创建者:ycj
*创建时间:2015-3-10
*文件说明:实现动态数组的增加,删除,查找,修改,排序,插入
**********************************************************/
#include "动态数组.h"


//初始化
void init(struct data *pdata)//使用之前初始化
{
pdata->p = NULL;//意味着还没有初始化
pdata->length = 0;//长度为0
pdata->stat = 0;//代表无序
pdata->reallength = 0; //实际长度
}


//使用之后初始化
void reinit(struct data *pdata)
{
if (pdata->p == NULL)
{
return;
}
else
{
free(pdata->p);//释放内存
pdata->p = NULL;//意味着还没有初始化
pdata->length = 0;//长度为0
pdata->stat = 0;//代表无序
pdata->reallength = 0; //实际长度
}
}


//增加一个数据
void addobject(struct data *pdata, int num)
{
if (pdata->p == NULL)
{
pdata->p = (int *)malloc(sizeof(int));//增加一个数据
pdata->length += 1;//数组标识增加一个元素
pdata->reallength += 1; //实际长度
pdata->p[pdata->length - 1] = num;//赋值
}
else
{
if (pdata->length == pdata->reallength)//判断是否有空余空间
{
pdata->p = (int *)realloc(pdata->p, (pdata->length + 1) * sizeof(int));
pdata->length += 1;//数组标识增加一个元素
pdata->reallength += 1; //实际长度
pdata->p[pdata->length - 1] = num;//赋值
}
else
{
pdata->length += 1;//数组标识增加一个元素
pdata->p[pdata->length - 1] = num;//赋值
}
}
}


//增加一个数组
void addobjects(struct data *pdata, int *pnum, int n)//数组作为参数退化为指针
{
if (pdata->p == NULL)
{
pdata->p = (int *)malloc(sizeof(int) * n);//增加n个数据
for (int i = 0; i < n; i++)
{
pdata->p[i] = pnum[i];//拷贝数组
}
pdata->length += n;//数组标识增加n个元素
pdata->reallength += n; //实际长度
}
else
{
if (pdata->length + n <= pdata->reallength)//判断是否有空余空间
{
for (int i = 0; i < n; i++)
{
pdata->p[i + pdata->length] = pnum[i];//拷贝数组
}
pdata->length += n;//数组标识增加n个元素
}
else
{
pdata->p = (int *)realloc(pdata->p, (pdata->length + n) * sizeof(int));//重新分为内存
for (int i = 0; i < n; i++)
{
pdata->p[i + pdata->length] = pnum[i];//拷贝数组
}
pdata->length += n;//数组标识增加n个元素
pdata->reallength += n; //实际长度
}
}

}


//打印所有的数据
void printfall(struct data *pdata)
{
for (int i = 0; i < pdata->length; i++)
{
printf("%d\n", pdata->p[i]);
}
}


//数组排序(冒泡法)
void sort(struct data *pdata, int flag)//obj=0;从小到大,否则从大到小
{
if (flag == 0)
{
for (int i = 0; i < pdata->length - 1; i++)
{
for (int j = 0; j < pdata->length - 1 - i; j++)
{
if (pdata->p[j] > pdata->p[j + 1])
{
//交换数据
pdata->p[j] = pdata->p[j] ^ pdata->p[j + 1];
pdata->p[j + 1] = pdata->p[j] ^ pdata->p[j + 1];
pdata->p[j] = pdata->p[j] ^ pdata->p[j + 1];
}
}
}
pdata->stat = 1;//代表有序,从小到大
}
else
{
for (int i = 0; i < pdata->length - 1; i++)
{
for (int j = 0; j < pdata->length - 1 - i; j++)
{
if (pdata->p[j] < pdata->p[j + 1])
{
//交换数据
pdata->p[j] = pdata->p[j] ^ pdata->p[j + 1];
pdata->p[j + 1] = pdata->p[j] ^ pdata->p[j + 1];
pdata->p[j] = pdata->p[j] ^ pdata->p[j + 1];
}
}
}
pdata->stat = 2;//代表有序,从大到小
}
}


//查找数据
int * finddata(struct data *pdata, int num)
{
if (pdata->stat == 0)
{
for (int i = 1; i < pdata->length; i++)//顺序循环
{
//printf("查找第%d次\n", i);
if (num == pdata->p[i])//判定是否相等
{
return &pdata->p[i];//返回一个地址
}
}
return NULL;
}
else if (pdata->stat == 1)//二分查找法,从小到大
{
int tou = 0;
int wei = pdata->length - 1;
int zhong = (tou + wei) / 2;
while (tou <= wei)//循环终止条件
{
zhong = (tou + wei) / 2;
//printf("tou=%d,zhong=%d,wei=%d\n", tou, zhong, wei);
if (num == pdata->p[zhong])
{
return &pdata->p[zhong];//返回一个地址
}
else if (num > pdata->p[zhong])
{
tou = zhong + 1;
}
else
{
wei = zhong - 1;
}
}
return NULL;
}
else//二分查找法//从大到小
{
int tou = 0;
int wei = pdata->length - 1;
int zhong = (tou + wei) / 2;
while (tou <= wei)//循环终止条件
{
zhong = (tou + wei) / 2;
//printf("tou=%d,zhong=%d,wei=%d\n", tou, zhong, wei);
if (num == pdata->p[zhong])
{
return &pdata->p[zhong];//返回一个地址
}
else if (num < pdata->p[zhong])
{
tou = zhong + 1;
}
else
{
wei = zhong - 1;
}
}
return NULL;
}
}


//从一个地址开始,N个范围之内找到(内部调用)
int * find(int *p, int num, int n)
{
for (int i = 0; i < n; i++)
{
if (p[i] == num)
{
return p + i;
}
}
return NULL;//代表没有找到
}


//返回一个结构体,包含找到元素的个数和地址
struct findres findalldata(struct data *pdata, int num)
{
//实际开发用链表,一个接着,接着(这里用数组简单实现)
struct findres res1;//构建结构体变量
int i = 0;
for (int *p = find(pdata->p, num, pdata->length); p != NULL; p = find(p + 1, num, (pdata->length) - (p - pdata->p + 1)))
{
i++;
}
//printf("%d\n", i);
res1.n = i;
int **pint = (int **)malloc(sizeof(int *) * i);//指针数组
res1.pp = pint;
int j = 0;
for (int *p = find(pdata->p, num, pdata->length); p != NULL; j++, p = find(p + 1, num, (pdata->length) - (p - pdata->p + 1)))
{
pint[j] = p;//循环赋值
//printf("%p,%d\n", pint[j], *pint[j]);
}
return res1;
}


//实现修改
void change(struct data *pdata, int oldnum, int newnum)
{
int *p = finddata(pdata, oldnum);
if (p == NULL)
{
printf("修改失败,没有找到\n");
}
else
{
*p = newnum;//修改数据
}
}


//数据插入
void insert(struct data *pdata, int num, int insertnum, int headback)
{
int *p = finddata(pdata, num);//找到数据
if (p == NULL)
{
printf("插入失败,没有找到\n");
return;//没有找到
}
else
{
//找到,1前面插入,否则后面插入
if (headback == 1)
{
if (pdata->length < pdata->reallength)//不需要分配内存
{
int curr = p - pdata->p; //获取要插入位置的下标
for (int i = pdata->length - 1; i >= curr; i--)
{
pdata->p[i + 1] = pdata->p[i];//从后往前移动
}
pdata->p[curr] = insertnum;
pdata->length += 1;//长度加1
}
else
{
int curr = p - pdata->p;
pdata->p = (int *)realloc(pdata->p, (pdata->length + 1) * sizeof(int));//增加分配内存
pdata->reallength += 1; //实际长度
for (int i = pdata->length - 1; i >= curr; i--)
{
pdata->p[i + 1] = pdata->p[i];//从后往前移动
}
pdata->length += 1;//长度加1
pdata->p[curr] = insertnum;//实现插入,前面插入
}


}
else
{
if (pdata->length < pdata->reallength)//不需要分配内存
{
int curr = p - pdata->p; //获取要插入位置的下标
for (int i = pdata->length - 1; i > curr; i--)
{
pdata->p[i + 1] = pdata->p[i];//从后往前移动
}
pdata->p[curr + 1] = insertnum;//实现插入,后面插入
pdata->length += 1;//长度加1
}
else
{
int curr = p - pdata->p;
pdata->p = (int *)realloc(pdata->p, (pdata->length + 1) * sizeof(int));//增加分配内存
pdata->reallength += 1; //实际长度
for (int i = pdata->length - 1; i > curr; i--)
{
pdata->p[i + 1] = pdata->p[i];//从后往前移动
}
pdata->p[curr + 1] = insertnum;//实现插入,后面插入
pdata->length += 1;//长度加1
}
}
}
return;
}


//删除第一个找到的数据
void deletone(struct data *pdata, int num)
{
int *p = finddata(pdata, num);//查找数据
if (p == NULL)
{
printf("not find!\n");
return;//没有找到
}
else
{
int curr = p - pdata->p;//元素的下标
//printf("%d,%p\n", *p, p);
//printf("%d,%p\n", pdata->p[curr], &pdata->p[curr]);
for (int i = curr; i < pdata->length - 1; i++)
{
pdata->p[i] = pdata->p[i + 1];
}
pdata->length -= 1;//数组元素减去1
}
}


//删除全部
void  deleteall(struct data *pdata, int num) //删除所有能找到的数据
{
for (int *p = finddata(pdata, num); p != NULL; p = finddata(pdata, num))
{
int  curr = p - pdata->p;//cur就是要删除的下标
//printf("\n%d,%p", *p, p);
//printf("\n%d,%p", pdata->p[curr], &pdata->p[curr]);//输出数据
for (int i = curr; i < pdata->length - 1; i++)
{
pdata->p[i] = pdata->p[i + 1];//从后向前移动
}
pdata->length -= 1;//数组元素减去1


}
}


/*********************************************************
*文件名: test.c
*创建者:ycj
*创建时间:2015-3-10
*文件说明:测试各模块
**********************************************************/

#include <stdio.h>
#include <stdlib.h>
#include "动态数组.h"
#pragma comment(lib, "数组lib.lib")//引用静态库


//两种测试方式
void main()
{
int a[10] = { 231, 112, 1233, 14123, 112, 116, 71, 11, 29, 11252 };
struct data *pdata = (struct data *)malloc(sizeof(struct data));//pdata存在堆上
init(pdata);
addobject(pdata, 100);
reinit(pdata);


addobject(pdata, 10);
addobjects(pdata, a, 10);
change(pdata, 14123, 0);
deletone(pdata, 11252);
sort(pdata, 0);//obj=0;从小到大,否则从大到小
printfall(pdata);


printf("\n\n");
//测试insert模块
insert(pdata, 29, 1111, 0);
insert(pdata, 29, 1111, 1);


printfall(pdata);


printf("\n\n");


//测试finddata模块
//块语句屏蔽信息
{
int *pfind = finddata(pdata, 1233);
if (pfind != NULL)
{
printf("查找结果:%d,%p\n", *pfind, pfind);//输出查找结果
}
else
{
printf("not find\n");
}
}


{
int *pfind = finddata(pdata, 1);
if (pfind != NULL)
{
printf("查找结果:%d,%p\n", *pfind, pfind);//输出查找结果
}
else
{
printf("not find\n");
}
}


//测试findalldata模块
{
struct findres res1 = findalldata(pdata, 112);
for (int i = 0; i < res1.n; i++)
{
printf("res1 %p,%d\n", *(res1.pp + i), **(res1.pp + i));//二级指针遍历指针数组
}
free(res1.pp);//释放内存
}


system("pause");
}






void main1()
{
int a[10] = { 231, 112, 1233, 14123, 112, 116, 71, 11, 29, 11252 };
struct data  data1;//data1存在栈上
//测试init,addobject,addobjects,change,deletone,sort,printfall模块
init(&data1);
addobject(&data1, 100);
reinit(&data1);


addobject(&data1, 10);
addobjects(&data1, a, 10);
change(&data1, 14123, 0);
deletone(&data1, 11252);
sort(&data1, 0);//obj=0;从小到大,否则从大到小
printfall(&data1);


printf("\n\n");
//测试insert模块
insert(&data1, 29, 1111, 0);
insert(&data1, 29, 1111, 1);


printfall(&data1);


printf("\n\n");


//测试finddata模块
//块语句屏蔽信息
{
int *pfind = finddata(&data1, 1233);
if (pfind != NULL)
{
printf("查找结果:%d,%p\n", *pfind, pfind);//输出查找结果
}
else
{
printf("not find\n");
}
}


{
int *pfind = finddata(&data1, 1);
if (pfind != NULL)
{
printf("查找结果:%d,%p\n", *pfind, pfind);//输出查找结果
}
else
{
printf("not find\n");
}
}


//测试findalldata模块
{
struct findres res1 = findalldata(&data1, 112);
for (int i = 0; i < res1.n; i++)
{
printf("res1 %p,%d\n", *(res1.pp + i), **(res1.pp + i));//二级指针遍历指针数组
}
free(res1.pp);//释放内存
}


system("pause");
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值