C语言数组的删除,插入

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C语言数组的删除,插入相关的知识,希望对你有一定的参考价值。

我做了一个学生成绩管理系统,菜单驱动的,结构体数组定义,这是代码的定义与菜单函数:
#define STU_NUM 15 /* 规定的学生人数 */
#define COURSE_NUM 2 /* 最多的考试科目 */
#define MAX_NUM 50 /* 允许的最大学生数 */
#include<stdio.h>
FILE *fp;
struct student

long int number; /* 每个学生的学号 */
char name[10]; /* 每个学生的姓名 */
int score[COURSE_NUM]; /* 每个学生M门功课的成绩 */
int sum; /* 每个学生的总成绩 */
float average; /* 每个学生的平均成绩 */
s[MAX_NUM]=0,'abc',0,0,0;

char menu(void)/*菜单函数*/

char ch;
printf("\nManagement for Students' scores \n");
printf("1 Built record\n");/* 建立生成记录,计算出总分和平均值*/
printf("2 List record \n");/*显示记录_在屏幕中打印所有学生成绩*/
printf("3 Delete record\n");/*删除记录_用后面的数据替换前一个*/
printf("4 Modify record \n");/*修改记录_对要修改的数据重新复值*/
printf("5 Search record \n");/*查询记录_输入学生学号,输出对应的成绩数据*/
printf("6 Sort Score in descending order by sum \n");/*按总分排序_降序排列,打印出学生姓名和成绩*/
printf("7 Sort Score in ascending order by sum\n");/*按总分排序_升序排列,打印出学生姓名和成绩*/
printf("8 Sort Score in descending order by num \n");/*按学号排序_按学号降序排列,打印出学生姓名和成绩*/
printf("9 Append record\n");/*在任意位置添加一个学号,输入姓名与成绩*/
printf("w Write to a File \n");/*写入文件*/
printf("r Read from a File \n");/*从文件中读出成绩*/
printf("0 Exit\n ");
printf("Please Input your choice:");
scanf(" %c",&ch);
return(ch);

是这样用的:先选1,输入并生成STU_NUM个记录,也就是defined的15个学生,因为需要添加其他学生的函数,结构体就要越界,所以定义了MAX_NUM 即允许的最大容量。
不过3和9 删除与插入总是写不好,还请熟练的老手帮我把把关,
把delete()和append()函数写了,多谢大家!
这是代码的一部分,如果有感觉不详细的地方可以问我,我可以追问。
我会长期等的,要符合我代码要求。不要随便搞以个就复制粘贴
好好写的话 50块大奖就属于你啦!

建议加一个全局变量用于存储当前有多少有效数据。

就先假设是CURRENT_NUM好了

删除的话:

//假设删除第target位
//(数组下标为从0~CURRENT_NUM-1 如果不一样的话稍微改下就好)

if(target<0||target>=CURRENT_NUM)

    //越界处理
else 
    for(int i=target+1;i<CURRENT_NUM;i++)
        s[i-1]=s[i];
    CURRENT_NUM--;

插入的话思想类似

//假设插入第target位
//(数组下标为从0~CURRENT_NUM-1 如果不一样的话稍微改下就好)

if(target<0||target>CURRENT_NUM)    //target可以等于CURRNET_NUM是因为可以插入到数组尾 

    //越界处理
else 
    for(int i=target;i<CURRENT_NUM;i++)
        s[i+1]=s[i];
    //对s[target]进行赋值
    CURRENT_NUM++; 

参考技术A #include<stdio.h>
void paixu(int a[])

int i,j=a[0];
for(i=1;i<sizeof(a);i++)

if(a[i-1]>a[i])

j=a[i-1];
a[i-1]=a[i];
a[i]=j;


for(i=0;i<sizeof(a);i++)
printf("%d",a[i]);
void insert(int k,int a[])

int i,j;
for(i=0;i<sizeof(a);i++)

if(k>a[i]) continue;
j=i;

for(i=sizeof(a);i>j;)

a[i]=a[--i];
a[j]=k;
for(i=0;i<sizeof(a);i++)
printf("%d",a[i]);
void shanchu(int k,int a[])

int i,j;
for(i=0;i<sizeof(a);i++)

if(k!=a[i]) continue;
j=i;

for(i=j;i<sizeof(a);i++)

a[i]=a[i+1];

for(i=0;i<sizeof(a);i++)
printf("%d",a[i]);
void chaxun(int k,int a[])

int i;
for(i=0;i<sizeof(a);i++)

if(k!=a[i]) continue;
if(i>=sizeof(a))

printf("没有找到匹配的值!");
break;

else

printf("%",i);
break;

void main()

int i,a[20]=3,1,4,2,6,8,7,9,0,11,5;
for(i=0;i<sizeof(a);i++)
printf("%d",a[i]);
chaxun(5,a);
insert(10,a);
shanchu(6,a);

❤❤❤❤顺序表的实现(c语言)----数据结构


对于数据结构来说,最基本的就是顺序表了,也就是动态数组了,那么动态数组到底该怎么来实现它呢,可能对于刚学习数据结构的人来说还是有点难理解的,下面的就具体来写一写动态数组的实现过程。
首先我们来想一下对于一个动态的数组,它要能实现什么功能呢? 动态数组相比静态数组最主要的功能那当然是可以动态开辟数组的长度了,当然还包括可以删除某个数组中的元素。下面我们来具体实现这些功能。

1.定义数组的结构体

对于一个动态开辟的数组,那么我们怎么能做到呢,这里我们首先想到可能就是用一个结构体来封装一些数组的属性, 从而来达到我们想要的操作。

首先结构体中首先肯定要先定义一个数组,那么数组我们应该定义为什么类型呢? 一般来说我们是不知道用户传过来的数据是什么类型的,所以为了可以接收任意类型的数据我们可以将数据类型定义为void*) ,**这样的话我们就可以接收任意类型的数据了,包括自定义类型的数据。**当然我们还需要知道数组中已有元素的个数,以及数组的容量,这样的话方便我们后续进行扩容操作。

struct dynamicArray

	void** parray;//数组中的数据类型定义为void* 
	int mSize; //数组实际大小
	int mCapacity;//数组容量
;

2.初始化数组

对于初始化数组来说,就是开辟出一个固定容量的数组,方便后续的操作。具体看下面代码

struct dynamicArray* initArray(int capacity)

	if (capacity <= 0)//如果最大容量小于等于0直接返回
	
		return NULL;
	
	//为结构体开辟一块空间
	struct dynamicArray* array = malloc(sizeof(struct dynamicArray)); 
	//开辟失败直接返回NULL
	if (array == NULL)
	
		return NULL;
	
	//初始化结构体中的一些变量
	array->mCapacity = capacity;
	array->mSize = 0;
	//给结构体中的数组开辟一块capacity的空间
	array->parray = malloc(sizeof(void*) * array->mCapacity);
	return array;

3.按位置插入元素

**对于元素的插入,我们需要注意的是数组的大小是否达到了它的容量,如果到达了它的容量,我们就需要进行扩容操作。**下面看代码具体实现过程。注释写的很清楚

void insertArray(struct dynamicArray* array, int pos, void* date)

	if (array == NULL)
	
		return;
	
	if (date == NULL)
	
		return;
	
	//判断位置的合理性
	if (pos<0 || pos>array->mSize)
	
		pos = array->mSize;
	
	//判断当前数组容量是否已经满了,满了的话,要进行扩容操作
	if (array->mSize == array->mCapacity)
	
		//设置新的量为之前容量的两倍
		int newCapacity = array->mCapacity * 2;
		//按照新的容量开辟在堆区开辟一块新的空间
		void** newSpace = malloc(sizeof(void*) * newCapacity);
		//将之前数组中的元素拷贝到新的空间之中
		memcpy(newSpace, array->parray, sizeof(void*) * array->mCapacity);
		//将之前数组空间释放掉
		free(array->parray);
		//将数组指向这块新空间
		array->parray = newSpace;
		//将数组的容量也进行更新
		array->mCapacity = newCapacity;
	
	//将pos位置后面的数据都往后一位
	for (int i = array->mSize - 1; i >= pos; i--)
	
		array->parray[i + 1] = array->parray[i];
	
	//将数据插入到pos位置
	array->parray[pos] = date;
	//对数组的大小进行更新
	array->mSize++;

4.删除元素

对于删除元素,我这里提供两种不同的方法来进行删除,一种是通过位置来进行删除,一种是通过数据类型来进行删除。

4.1删除某个位置的元素

在数组中删除pos位置元素,最简单的方式就是直接覆盖掉pos位置的元素,然后将数组中的元素的个数减一就好了。这个比较简单,直接看下面的代码。

//删除某个位置的元素
void deletDate(struct dynamicArray* arr, int pos)

	if (arr == NULL)
		return;
	if (pos<0 || pos>arr->mSize - 1)
	
		return;
	

	for (int i = pos; i < arr->mSize - 1; i++)
	
		arr->parray[i] = arr->parray[i + 1];
	
	arr->mSize--;

4.2通过数据来删除某个元素

通过数据来删除某个元素,比通过位置来删除某个数据要复杂一点,因为我们设定的数据类型为void* 的数据类型,我们也不知道用户会传什么样的数据类型给我们。所以我们就要想一种通用的数据比较方法。这里我们就可以用回调函数来实现这一功能,关于回调函数,可以去看一下下面这篇博客中的简单介绍 第6小结函数指针数组中有简单介绍回调函数
下面我设计了一个myCompar的函数指针,用来做回调函数,对于怎么用,在后面测试环节我会将到。

void removeDate(struct dynamicArray* arr, void* date, int(*myCompar)(void*, void*))

	if (arr == NULL)
		return;
	if (date == NULL)
		return;

	for (int i = 0; i < arr->mSize; i++)
	
		if (myCompar(arr->parray[i], date))
		
			deletDate(arr, i);
			break;
		
	


5.遍历数组

遍历数组,我们主要是想要看到数组中的内容,这里我们同样提供一个回调函数来遍历数组。

void foreachArray(struct dynamicArray* array, void(*myForeach)(void*))

	if (array == NULL)
	
		return;
	

	for (int i = 0; i < array->mSize; i++)
	
		myForeach(array->parray[i]);
	

6.销毁数组

销毁数组时,我们要注意我们在堆区开辟了多少几块空间,这里我们首先是为结构体开辟了一块空间,然后结构体中的数组我们又开辟了一块空间,所以我们进行释放的时候,应该先释放里面的数组,然后在释放外面的结构体。

void destoryArr(struct dynamicArray* array)

	if (array == NULL)
		return;
	if (array->parray != NULL) //先删除里面的
	
		free(array->parray);
		array->parray = NULL;
	

	free(array);
	array = NULL;

7.测试代码功能

这里我们选用一个自定义的数据类型来进行测试。然后根据数据类型完成比较数据和打印数据两个回调函数。

//定义一个人的数据类型
struct Person

	char name[50];
	int age;
;
//比较数据信息,用作回调函数
int mycampar(void* date1, void* date2)

	struct Person* p1 = date1;
	struct Person* p2 = date2;
	//p1,p2数据相同时返回真
	return (strcmp(p1->name, p2->name) == 0) && (p1->age == p2->age);


//打印信息,用作遍历数组的回调函数
void myPrint(void* date)

	struct Person* p = date;
	printf("姓名:%s  年龄: %d\\n", p->name, p->age);


void test01()

	//开辟一个容量为5 的数组
	struct dynamicArray* array= initArray(5);
	printf("数组扩容前容量: %d\\n", array->mCapacity);
	//创建6个数据
	struct Person p1 =  "陈",10 ;
	struct Person p2 =  "卢",12 ;
	struct Person p3 =  "张",14 ;
	struct Person p4 =  "王",15 ;
	struct Person p5 =  "周",11 ;
	struct Person p6 =  "李",16 ;
	//插入这6个数据看是否容量会扩增
	insertArray(array, 0, &p1);
	insertArray(array, 1, &p2);
	insertArray(array, 0, &p3);
	insertArray(array, 2, &p4);
	insertArray(array, 6, &p5);
	insertArray(array, 5, &p6);
	printf("数组扩容后容量: %d\\n", array->mCapacity);
	//调用回调函数打印数组内用
	foreachArray(array, myPrint);

	printf("-------------\\n");
	deletDate(array, 1);
	foreachArray(array, myPrint);

	printf("-------------\\n");
	struct Person p = "李",16;
	//调用回调函数比较数据信息
	removeDate(array, &p, mycampar);
	foreachArray(array, myPrint);
	destoryArr(array);
	array = NULL;




int main()

	test01();
	return 0;

下面是程序运行的结果

以上是关于C语言数组的删除,插入的主要内容,如果未能解决你的问题,请参考以下文章

c语言数组排序好输出问题

C语言求助。急急

c语言 查找最大元素

c语言编程,已经从小到大排好的一维9元素数组在插入一个数,按顺序,怎么写程序?谢谢

用C语言编写程序,实现在数组中指定位置插入一个新的数字?(数组不是排序好的)谢谢

请教一个 C语言 字符串数组之间比较的算法,谢谢