今天做一道经典递归,“字符串逆序”,并且不能使用C语言内置库函数,通过这道题,我们可以对递归有更深的认识

老规矩先看代码

void reverse_string(char* string)
{
	int sz = 0;
	while (string[sz] != '\0') {
		sz++;
	}
	if (sz<2) {
		return;
	}
	char* left = string;
	char* right = (string + sz - 1);
	int ret = *left;
	*left = *right;
	*right = string[sz];
    reverse_string(string+1);
	*right = ret;
}

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

下面看一下运行结果

我们可以看到,字符串逆序了,说明代码没问题
在这里插入图片描述

接下来我来解释解释其中的难点

我们知道,字符串逆序就是将字符串首尾字符交换,直到最中间的元素交换完,这就满足了我们递归的三个条件:

问题规模要越递越小,直到拆解成基本问题
拆解成的基本问题要保持和原问题思路一样
存在递归中止条件

也就是下面这张图的内容:
在这里插入图片描述
上图中,我们将递归进行拆解,函数功能首先需要将两个字符交换,其次每次交换后,首尾各“去掉一位”,也就是说,我们把字符串逆序问题拆解成了c和e进行交换,终止条件是只剩下d元素,也就是当我们检索到字符串长度的一半时,有的同学可能会多想奇偶数的问题,但是这个条件与字符串长度是奇偶数无关。

非小白可能一看就懂了,但是小白还是云里雾里的,没关系,我逐句讲解一下大家就明白了

int sz = 0;
	while (string[sz] != '\0') {
		sz++;
	}

由于不能使用库函数,这串代码代替库函数strlen的作用,计算字符串长度。

if (sz<2) {
		return;
	}

如果字符串长度小于2就不用交换了,这就是终止条件

char* left = string;//首指针,用来指向字符串首元素
char* right = (string + sz - 1);//尾指针,用来指向尾元素

这里我们通过指针将尾元素与首元素交换,交换完成后我们应该交换第二个元素和倒数第二个元素,也就是把第二个元素的地址传给reverse_string函数,如果思路是这样的,逆序的结果就会变成fabcde,我们会发现一个问题,首指针指向第二个元素了,尾指针怎么办?由于题目要求,只能有字符串这一个参数,并且leftright必须都要变化,所以我们发现right=string+sz-1,可以用计算出来的sz进行控制

int ret = *left;//用于保存第一个元素
*left = *right;
*right = string[sz];
reverse_string(string+1);//每次递归调用时,首指针后移

这段代码是核心,我们知道,计算sz时,从第一个字符读到‘\0’,就会停止,那么在将尾指针指向的元素地址赋值给首指针之前,我们先用临时变量保存第一个元素,然后再将‘\0’赋值给最后一个元素,这样每次递归,sz就相当于执行sz--操作,如下图所示
在这里插入图片描述

sz < 1时,函数return*right = ret;这条代码就就会将每次递归保存下来的首元素放进'\0'的位置
在这里插入图片描述

机智如你一定明白了吧!!!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Mr.水熊虫

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

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

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

打赏作者

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

抵扣说明:

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

余额充值