动态数组
优质
小牛编辑
142浏览
2023-12-01
array.h
#include<stdio.h>
#include<stdlib.h>
struct data
{
int *p;//指针保存数组的起始点
int length;//保存数组的长度
int stat;//0代表无序,1代表有序从小到大,2有序从大到小
int reallength;//实际分配的内存长度
};
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);//增加一个数组
void printfall(struct data *pdata);//打印所有的数据
int *finddata(struct data *pdata, int num);//返回第一个找到数据的地址
void sort(struct data *pdata, int obj);//obj=0,从小大到,否则从到小
void change(struct data *pdata, int oldnum, int newnum);//实现修改
void deleteone(struct data *pdata, int num);//删除第一个找到的数据
void deleteall(struct data *pdata, int num); //删除所有能找到的数据
//返回一片内存,包含所有找到的元素的首地址
struct findres findadlldata(struct data *pdata, int num);
//数据插入,1代表前面插入,0代表后面插入
void insert(struct data *pdata, int num, int insertnum, int headback);
array.c
#include"array.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个元素
pdata->length = n;//数组标识增加n个元素
pdata->reallength = n;//实际长度
for (int i = 0; i < n; i++)
{
pdata->p[i] = pnum[i];//拷贝数组
}
}
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 obj)//obj=0,从小大到,否则从da到小
{
if (obj == 0)
{
for (int i = 0; i < pdata->length - 1; i++)
{
for (int j = 0; j < pdata->length - i-1; j++)
{
if (pdata->p[j] > pdata->p[j + 1])// j >j+1
{
int temp = pdata->p[j]; //交换数据
pdata->p[j] = pdata->p[j + 1];
pdata->p[j + 1] = temp;
}
}
}
pdata->stat = 1;//代表从小到大
}
else
{
for (int i = 0; i < pdata->length - 1; i++)
{ //冒泡没循环一次,沉底一个极值
for (int j = 0; j < pdata->length - i-1; j++)
{
if (pdata->p[j] < pdata->p[j + 1])// j <j+1
{
//int temp = pdata->p[j]; //交换数据
//pdata->p[j] = pdata->p[j + 1];
//pdata->p[j + 1] = temp;
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];
//0011 0001 3 1
//p[j]0011
//p[j + 1]0001
// p[j] 0010
//p[j + 1]0001
// p[j] 0010
//p[j + 1]0011
//0001 a=a^b,b=a^b.a=a^b;
}
}
}
pdata->stat = 2;//代表从大到小
}
}
int * finddata(struct data *pdata, int num)
{
if (pdata->stat == 0)
{
for (int i = 0; i < pdata->length; i++)//顺序循环
{
printf("查找第%d次\n", i);
if (num == pdata->p[i])//判定是否相等
{
return &pdata->p[i];//返回一个地址
break;//跳出循环
}
}
return NULL;
}
else if (pdata->stat == 1) //二分查找法//从小到da
{
int shang = 0;//shang
int xia = pdata->length - 1;//下
while (shang <= xia)//循环终止条件,
{
int zhong = (shang + xia) / 2;
printf("%d,%d,%d\n", shang, zhong, xia);
if (pdata->p[zhong] == num)
{
return &pdata->p[zhong];//返回地址
}
else if (pdata->p[zhong] >num)
{
xia = zhong - 1;
}
else if (pdata->p[zhong]<num)
{
shang = zhong + 1;
}
}
return NULL;
}
else
{
int shang = 0;//shang
int xia = pdata->length - 1;//下
while (shang <= xia)//循环终止条件,
{
int zhong = (shang + xia) / 2;
printf("%d,%d,%d\n", shang, zhong, xia);
if (pdata->p[zhong] == num)
{
return &pdata->p[zhong];//返回地址
}
else if (pdata->p[zhong] >num)
{
//xia = zhong - 1;
shang = zhong + 1;
}
else if (pdata->p[zhong]<num)
{
//shang = zhong + 1;
xia = zhong - 1;
}
}
return NULL;
}
}
void change(struct data *pdata, int oldnum, int newnum)//实现修改
{
int *p = finddata(pdata, oldnum);
if (p == NULL)
{
printf("修改失败,没有找到");
return;
}
else
{
*p = newnum;//修改数据
}
}
////1代表前面插入,0代表后面插入
void insert(struct data *pdata, int num, int insertnum, int headback)//数据插入
{
int *p = finddata(pdata, num);//查找数据
if (p == NULL)
{
return ;//没有找到
}
else
{
//找到,前面插入 ,否则后面插入
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
}
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] = insertnum;//实现插入,前面插入
pdata->length++;//长度加1
}
}
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;//实现插入,hou插入
pdata->length++;//长度加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;//实现插入,hou插入
pdata->length++;//长度加1
}
}
}
}
//删除
void deleteone(struct data *pdata, int num)
{
int *p = finddata(pdata, num);//查找数据
if (p == NULL)
{
return ;//没有找到,删除,
}
else
{
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
}
}
//删除全部
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
}
}
int * find(int *p, int num,int n )//从一个地址开始,N个范围之内找到
{
for (int i = 0; i < n; i++)//循环
{
if (p[i] == num)//判断
{
return p + i;//返回找到的地址
break;
}
}
return NULL;//代表没有找到
}
struct findres findadlldata(struct data *pdata, int num)
{
struct findres res1;//构建结构体变量
int i = 0; //统计找到多少个。
for (int *p = find(pdata->p, num, pdata->length - 1);
p!=NULL;
p = find(p+1, num, (pdata->length - 1)-(p-pdata->p)))
{
i++;
}
res1.n = i;//长度
int **pint = (int **)malloc(sizeof(int *)* i);//指针数组
res1.pp = pint;
for (int *p = find(pdata->p, num, pdata->length - 1),j=0;
p != NULL;
j++, p = find(p + 1, num, (pdata->length - 1) - (p - pdata->p)))
{
pint[j] = p;//循环赋值
//printf("\n%p,%d\n", pint[j], *pint[j]);
}
return res1;
}
main.c
#include<stdio.h>
#include<stdlib.h>
#include"array.h"
void main()
{
int a[10] = { 231, 112, 1233, 14123, 523, 112, 71, 18, 29, 112 };
struct data data1;
init(&data1);
addobject(&data1, 10);
addobject(&data1, 11);
addobject(&data1, 12);
//reinit(&data1);
addobjects(&data1, a, 10);
printfall(&data1);
insert(&data1, 1233, 1988, 1);
insert(&data1, 1233, 1998, 0);
printfall(&data1);
system("pause");
}
void main2()
{
int a[10] = { 231, 112, 1233, 14123, 523, 112, 71, 18, 29, 112 };
struct data data1;
init(&data1);
addobject(&data1, 10);
addobject(&data1, 11);
addobject(&data1, 12);
//reinit(&data1);
addobjects(&data1, a, 10);
printfall(&data1);
struct findres resn= findadlldata(&data1, 112);//查找
for (int i = 0; i < resn.n; i++)
{
printf("\nresn %p,%d\n", *(resn.pp+i), **(resn.pp+i));//二级指针遍历指针数组
}
free(resn.pp);//释放内存
printfall(&data1);
system("pause");
}
void main1()
{
int a[10] = { 231, 112, 1233, 14123, 523,116, 71, 18, 29, 110 };
struct data data1;
init(&data1);
addobject(&data1, 10);
addobject(&data1, 11);
addobject(&data1, 12);
//reinit(&data1);
addobjects(&data1, a, 10);
printfall(&data1);
int *pfind = finddata(&data1, 1101);//查找
if (pfind != NULL)
{
printf("%d,%p", *pfind, pfind);//输出查找结果
}
else
{
printf("没有找到奥");
}
{
printf("\n\n");
sort(&data1, 0);
printfall(&data1);
int *pfind = finddata(&data1, 523);//查找
if (pfind != NULL)
{
printf("%d,%p", *pfind, pfind);//输出查找结果
}
else
{
printf("没有找到奥");
}
}
{
printf("\n\n");
sort(&data1, 1);
printfall(&data1);
int *pfind = finddata(&data1, 523);//查找
if (pfind != NULL)
{
printf("%d,%p", *pfind, pfind);//输出查找结果
}
else
{
printf("没有找到奥");
}
}
getchar();
}