(2)数据结构与算法-动态数组(2)

动态数组中间插入元素

回顾上节

上节是在动态数组的尾部添加一个元素
方式是再申请一个更大的空间,代替原空间
现在要在中间插入元素,该怎么办呢?

添加步骤

基于上一步的操作添加步骤
1)创建在中间添加节点的函数
传参的话,首先必传的是结构体指针
其次,要添加节点,所以一定还要传添加的中间值
最后,在中间添加一个元素的下标还要有,不然不知道加在哪

//MidNum是中间值,Index是要添加在的位置
void AddMid(struct DynamicArr *pArr,int MidNum,int Index){}

2)首先,要进行指针判断,万一传回来的是NULL怎么办。
其次,在中间添加元素是要将原添加位置的值及后面的值都往后移,万一后面的空间不够怎么办。需要之前的步骤

if (NULL == pArr)
	{
		return;
	}
	//同样也是先判断空间是否已满
	if (pArr->Cap == pArr->Num)
	{
		//先将原空间扩容
		pArr->Cap += 10;
		//中间指针变量定义新空间
		int *ptemp = (int*)malloc(sizeof(int)*pArr->Cap);
		//将原空间元素赋值到新空间
		for (int i = 0; i<pArr->Num; i++)
		{
			ptemp[i] = pArr->Head[i];
		}
		//赋值完后释放原空间
		free(pArr->Head);
		//将释放的空间重新指向现在的空间
		pArr->Head = ptemp;
	}

3)这一步就要实现将元素往后移。因为不只是后移一个元素,所以要用到循环,整体往后移

//将Index之后的元素后移
	for (int i = pArr->Num ;i>Index;i--)
		pArr->Head[i] = pArr->Head[i - 1];

int i = pArr->Num是从后往前循环赋值,到Index的位置结束
4)后移之后,位置就空出来了,添加元素就好了

//将MidNum插入Index的位置
	pArr->Head[Index] = MidNum;

5)此时,元素个数增加了

	//元素个数+1
	pArr->Num++;

6)主函数调用添加中间变量的函数

	//元素个数+1
	pArr->Num++;

整体代码如下:

#include<stdio.h>
#include<stdlib.h>
//定义动态数组结构体
struct DynamicArr
{
	//定义指针指向数组头
	int *Head;
	//定义记录容量
	int Cap;
	//记录数量
	int Num;
};
//初始化数组
void IniArr(struct DynamicArr *pArr)
{
	pArr->Cap = 5; 
	pArr->Head = (int*)malloc(sizeof(int)*pArr->Cap );
	pArr->Num = 0;
}
//在尾部增加节点
void AddLast(struct DynamicArr *pArr,int LastNum)
{
	//先判断空间是否已满
	if (pArr->Cap == pArr->Num )
	{
		//先将原空间扩容
		pArr->Cap += 10;
		//中间指针变量定义新空间
		int *ptemp = (int*)malloc(sizeof(int)*pArr->Cap );
		//将原空间元素赋值到新空间
		for (int i = 0;i<pArr->Num ;i++)
		{
			ptemp[i] = pArr->Head[i];
		}
		//赋值完就释放原空间
		free(pArr->Head );
	//将释放的空间重新指向现在的空间
		pArr->Head = ptemp ;
	}
	//在最后添加
	pArr->Head[pArr->Num] = LastNum;
	//增加数量
	pArr->Num++;
}
//输出
void print(struct DynamicArr *pArr)
{
	if (NULL == pArr)
		return;
	printf("%d %d\n",pArr->Cap ,pArr->Num );
	for (int i = 0; i < pArr->Num;i++)
		printf("%d ",pArr->Head [i]);
}
//在中间增加位置
void AddMid(struct DynamicArr *pArr,int MidNum,int Index)
{
	if (NULL == pArr)
		return;
	//同样也是先判断空间是否已满
	if (pArr->Cap == pArr->Num)
	{
		//先将原空间扩容
		pArr->Cap += 10;
		//中间指针变量定义新空间
		int *ptemp = (int*)malloc(sizeof(int)*pArr->Cap);
		//将原空间元素赋值到新空间
		for (int i = 0; i<pArr->Num; i++)				
			ptemp[i] = pArr->Head[i];
		//赋值完就释放原空间
		free(pArr->Head);
		//将释放的空间重新指向现在的空间
		pArr->Head = ptemp;
	}
	//将Index之后的元素后移
	for (int i = pArr->Num ;i>Index;i--)
		pArr->Head[i] = pArr->Head[i - 1];
	//将MidNum插入Index的位置
	pArr->Head[Index] = MidNum;
	//元素个数+1
	pArr->Num++;
}
int main()
{
	struct DynamicArr Arr;
	IniArr(&Arr);
	AddLast(&Arr, 1);
	AddLast(&Arr, 2);
	AddLast(&Arr, 3);
	//调用插入节点的函数
	AddMid(&Arr,1,1);
	print(&Arr);
	free(Arr.Head);
	system("pause");
	return 0;
}

输出:
5 4
1 1 2 3

特殊情况

如果要传入的下标不在数量的范围内,就会在最后赋值,但是要经过挪元素的代码,可以定义个判断语句,如果大于数量就直接在最后赋值,这样就更好了

//下标太大,不在范围内,判断语句,插后面
	if (Index>pArr->Num )
	{
		pArr->Num = Index;
	}

注意:一定要在挪之前判断,否则都挪完了,再写,也没啥效果了。

重改代码

把重复的代码封装成函数
重复的代码:

//同样也是先判断空间是否已满
	if (pArr->Cap == pArr->Num)
	{
		//先将原空间扩容
		pArr->Cap += 10;
		//中间指针变量定义新空间
		int *ptemp = (int*)malloc(sizeof(int)*pArr->Cap);
		//将原空间元素赋值到新空间
		for (int i = 0; i<pArr->Num; i++)
		{
			ptemp[i] = pArr->Head[i];
		}
		//赋值完就释放原空间
		free(pArr->Head);
		//将释放的空间重新指向现在的空间
		pArr->Head = ptemp;
	}

封装:直接调用就好了

void AddLast(struct DynamicArr *pArr, int LastNum)
{
	ArrP(pArr);
	//在最后添加
	pArr->Head[pArr->Num] = LastNum;
	//增加数量
	pArr->Num++;
}

整体代码如下:

#include<stdio.h>
#include<stdlib.h>
void IniArr(struct DynamicArr *pArr);
void AddLast(struct DynamicArr *pArr, int LastNum);
void print(struct DynamicArr *pArr);
void AddMid(struct DynamicArr *pArr, int MidNum, int Index);
void ArrP(struct DynamicArr *pArr);
//定义动态数组结构体
struct DynamicArr
{
	//定义指针指向数组头
	int *Head;
	//定义记录容量
	int Cap;
	//记录数量
	int Num;
};
//初始化数组
void IniArr(struct DynamicArr *pArr)
{
	pArr->Cap = 5;
	pArr->Head = (int*)malloc(sizeof(int)*pArr->Cap);
	pArr->Num = 0;
}
//在尾部增加节点
void AddLast(struct DynamicArr *pArr, int LastNum)
{
	ArrP(pArr);
	//在最后添加
	pArr->Head[pArr->Num] = LastNum;
	//增加数量
	pArr->Num++;
}
//输出
void print(struct DynamicArr *pArr)
{
	if (NULL == pArr)
	{
		return;
	}
	printf("%d %d\n", pArr->Cap, pArr->Num);
	for (int i = 0; i < pArr->Num; i++)
	{
		printf("%d ", pArr->Head[i]);
	}
}
//在中间增加位置
void AddMid(struct DynamicArr *pArr, int MidNum, int Index)
{
	if (NULL == pArr)
	{
		return;
	}
	ArrP(pArr);
	//下标太大,不在范围内,判断语句,插后面
	if (Index>pArr->Num )
	{
		pArr->Num = Index;
	}
	//将Index之后的元素后移
	for (int i = pArr->Num; i>Index; i--)
	{
		pArr->Head[i] = pArr->Head[i - 1];
	}
	//将MidNum插入Index的位置
	pArr->Head[Index] = MidNum;
	//元素个数+1
	pArr->Num++;
}
void ArrP(struct DynamicArr *pArr)
{
	//同样也是先判断空间是否已满
	if (pArr->Cap == pArr->Num)
	{
		//先将原空间扩容
		pArr->Cap += 10;
		//中间指针变量定义新空间
		int *ptemp = (int*)malloc(sizeof(int)*pArr->Cap);
		//将原空间元素赋值到新空间
		for (int i = 0; i<pArr->Num; i++)
		{
			ptemp[i] = pArr->Head[i];
		}
		//赋值完就释放原空间
		free(pArr->Head);
		//将释放的空间重新指向现在的空间
		pArr->Head = ptemp;
	}
}
int main()
{
	struct DynamicArr Arr;
	IniArr(&Arr);
	AddLast(&Arr, 1);
	AddLast(&Arr, 2);
	AddLast(&Arr, 3);
	//调用插入节点的函数
	AddMid(&Arr, 1, 1);
	AddMid(&Arr, 1, 4);
	AddMid(&Arr, 1, 3);
	print(&Arr);
	free(Arr.Head);
	system("pause");
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

沐鑫本鑫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值