C语言递归

在C语言的学习过程中,我们时常遇到一些特殊的问题,这些问题一步一步解决,且这些步骤都是这个问题的上一步或下一步(语文不好,不太会形容,555),这时候,我们就可以使用递归。
递归其实就是函数自己调用自己链表的问题与一些树的问题常用它来解决。著名的深度优先搜索(DFS)就可以通过递归实现。
接下来给出几个简单例题帮助大家理解:

例1:非常经典的斐波那契数

#include <stdio.h>
int fibonacci(int n)
{
	if(n <= 2) {
		return 1;//第一、二个都是1。
	} else {
	    return fibonacci(n - 1) + fibonacci(n - 2);
    }//每个斐波那契数是它前两个的和,用递归来实现。
}
int main(void) {
	int n;
	printf("请输入你想输出第几项的斐波那契数:\n");
	scanf("%d", &n);
	printf("%d\n", fibonacci(n));
	return 0;
}

例2:非常简单的一道二叉树题目

在这里插入图片描述

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */
int maxDepth(struct TreeNode *root) {
    if (root == NULL) return 0;
    return fmax(maxDepth(root->left), maxDepth(root->right)) + 1;
}//每个结点的高度是它下面两个高度的最大值再加一,用递归实现。

例3:又是一道二叉树的题:

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

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */
bool hasPathSum(struct TreeNode *root, int sum) {
    if (root == NULL) {
        return false;
    }//没有路,返回false。
    if (root->left == NULL && root->right == NULL) {
        return sum == root->val;
    }//接下来无路可走,从头走到结束了,如果总和等于target,则返回true,找到,否则返回false。
    return hasPathSum(root->left, sum - root->val) || hasPathSum(root->right, sum - root->val);
}//最后递归,分别向左右两边找。

例4:全排列问题(深度优先搜索)

力扣46.全排列
给定一个 没有重复 数字的序列,返回其所有可能的全排列。

/**
 * Return an array of arrays of size *returnSize.
 * The sizes of the arrays are returned as *returnColumnSizes array.
 * Note: Both returned array and *columnSizes array must be malloced, assume caller calls free().
 */
int cnt;
void dfs(int step, int* nums, int numsSize, int** ret, int* path, bool* book) {
//step先从0开始
	int i;
	if (step == numsSize) {
		//找到一种排列方式。
        ret[cnt] = (int*)malloc(sizeof(int) * numsSize);
        for(int i=0;i<numsSize;++i){
            ret[cnt][i]=path[i];
        }
        //放到答案的数组里
        cnt++;//计数器加1
		return;
	}
	for (i = 0; i < numsSize; i++) {
        if (book[i]) {
            continue;
            //这个值被用过,找下一个。
        }
        //值没被用过,那这次就把它加上。
        path[step] = nums[i];
        book[i] = true;
        //这次用了这个值,接下来找下一个位置的。
        dfs(step + 1, nums, numsSize, ret, path, book);
        //注意step + 1
        book[i] = false;
        //递归到最后一步跳出来了,这个值相当于上一次用过了,下一次还要用,book归位,表示还未用,这步十分关键。
	}
    return;
}

int** permute(int* nums, int numsSize, int* returnSize, int** returnColumnSizes) {
	cnt = 0;//计数器最开始为0
    *returnSize = 1;
    for (i = 1; i <= numsSize; i++) {
        *returnSize *= i;
    }//数学方式计算应该有多少种全排列。
    *returnColumnSizes = (int*)malloc(sizeof(int) * (*returnSize));
    for (int i = 0; i < (*returnSize); i++) {
        (*returnColumnSizes)[i] = numsSize;
    }
    bool* book = (bool*)calloc(numsSize, sizeof(bool));
    //book用来判断一个值是否被用过。
	int** ret = (int**)malloc(sizeof(int*)*(*returnSize));
    int* path = (int*)malloc(sizeof(int) * numsSize);
    //初始化一个路径数组用来记录每一次全排列。
	dfs(0, nums, numsSize, ret, path, book);
    return ret;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值