逆序数组(递归和非递归)(详细)

逆序数组 递归和非递归

在这里插入图片描述

一.非递归

思路:将第一个元素和最后一个元素交换,再将第二个元素和倒数第二个元素交换…直到所有元素全部交换

假设有一个数组arr[]=“abcdef”,我们令它的第一个元素为arr[left],最后一个元素为arr[right],那么我们就需要如下交换
在这里插入图片描述在这里插入图片描述

从上面的流程图可以看出当left<right时 ,便进行下一步交换,反之,就结束程序,这里直接上代码

void Reverse(char* arr)
{
	int left = 0;
	int right = strlen(arr) - 1;//strlen用于求数组长度,但由于数组下标
	while (right > left)       //是从0开始的,所以最后一个元素的下标是
	{                         //数组长度-1,6-1=5
		char tmp = arr[left];
		arr[left] = arr[right];
		arr[right] = tmp;//以上三步是将arr[left]和arr[right]交换
		right--;//右坐标向左移1
		left++;//左坐标向右移1
	}//当left不再小于right时表明已经逆移完全,结束循环

}
int main()
{
	char arr[] = "abcdef";
	Reverse(arr);
	printf("%s", arr);
	return 0;
}

二.递归

思路:我们可以把这个问题拆成两步。第一步:交换a和f。第二步:再用函数Reverse交换bcde
在这里插入图片描述

这里我们首先将a和 f交换

    int left = 0;
	int right = strlen(arr)-1;
	char tmp = arr[left];
	//这里有缺陷
	arr[left] = arr[right];
	arr[right] = tmp;
	//这里有缺陷
	Reverse(arr + 1);

逆序完第一次后我们需要让左坐标+1,所以我们传Reverse(arr+1),但在这里有个问题,逆序完第一次时,再逆序第二次时,你的left确实+1,但right并未改变,因为 right = strlen(arr)-1,而strlen是遇到’\0’,才会停下,但你这里’\0’但位置并未发生改变,所以right永远指向同一位置。
在这里插入图片描述
想要解决它,其实只需要将a的位置变为’\0’就可以了,所以我们需要令arr[5]=‘\0’ (这里为了方便,我直接写的下标)。但还是有个问题,就是如果先交换再赋值的话,那么a就会变为’\0’,得不到正确答案,所以我们需要一个临时变量先将a储存起来,再赋值’\0’,这样arr[5]=‘\0’,再进行Rverse(arr+1),right就指向e,最后再将a给arr[5]。
在这里插入图片描述
最后赋值
在这里插入图片描述

    int left = 0;
	int right = strlen(arr)-1;
	char tmp = arr[left];//把a存到tmp里
	arr[right] = arr[left];//把f交换到原来a的位置(也就是arr[0])
	arr[right] = '\0';//令原来放f的位置(也就是arr[5])放'\0'
	Reverse(arr+1);
	
	arr[right] = tmp;//再把a给放'\0'的位置(也就是arr[5])


这样是不是就可以运行了呢?其实还有一个问题,就是递归如果没有限制条件的话,那么就会成为死递归,导致系统崩溃,所以我们需要加入限制条件:

在这里插入图片描述

if (strlen(arr + 1) >= 2)
	{
		Reverse(arr + 1);
	}

这样的话程序就完成啦,来看看完整代码

void Reverse(char* arr)
{
	int left = 0;
	int right = strlen(arr)-1;
	char tmp = arr[left];
	arr[left] = arr[right];
	arr[right] = '\0';
	if (strlen(arr + 1) >= 2)
	{
		Reverse(arr + 1);
	}
	 arr[right]= tmp;


}
int main()
{
	char arr[] = "abcdef";
	Reverse(arr);
	printf("%s", arr);
	return 0;
}

在这里插入图片描述
在这里插入图片描述

  • 26
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 18
    评论
评论 18
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

咸蛋挞

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

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

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

打赏作者

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

抵扣说明:

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

余额充值