数组反向递归找父id_数据结构教程之递归习题复习

本文介绍了递归在多种数据结构问题中的应用,包括计算平均值、确定数字位数、楼梯上楼问题、链表节点计数、正反向遍历及删除操作,以及模式匹配。通过具体的递归算法实现,展示了递归在解决复杂问题时的简洁性和高效性。
摘要由CSDN通过智能技术生成

递归

  • 1.有以下递归函数
    void fun(int n)
    {
    if(n == 1)
    {
    printf("a:%d\n", n);
    }
    else
    {
    printf("b:%d\n", n); // 5 4 3 2
    fun(n - 1);
    printf("c:%d\n", n);
    }
    }
    • 答:
      b: 5
      b: 4
      b: 3
      b: 2
      a: 1
      c: 2
      c: 3
      c: 4
      c: 5
    • 调用递归函数fun(5)时,先递归到递归出口,然后求值。
    • 这里的递归出口语句是printf("a:%d\n", n),
    • 递归时执行的语句是printf("b:%d\d", n),
    • 求值时执行的语句是printf("c:%d\n", n)
    • 分析调用fun(5)的输出结果
  • 2.已知A[0..n-1]为整数数组,设计一个递归算法求这个n个元素的平均值。
    • 设avg(A, i)返回A[0..i]共i+1个元素的平均值,则递归模型如下:
      avg(A, i) = A[0]   当i=0
      avg(A, i) = (avg(A, i - 1) * i + A[i]) / (i + 1) 其他情况
    • 对应的递归算法如下:
      float avg(int A[], int i)
      {
      if(i == 0)
      {
      return(A[0]);
      }
      else
      {
      return( (avg(A, i - 1) * i + A[i]) / (i + 1) );
      }
      }
    • 求A[n]中n个元素平均值的调用方式为avg(A, n - 1)
    • 答:
  • 3.设计一个算法求正整数n的位数
    • 设f(n)为整数n的位数,其递归模型如下
      f(n) = 1   当n<10时
      f(n) = f(n / 10) + 1 其他情况
    • 对应的递归算法如下:
      int fun(int n)
      {
      if(n < 10)
      {
      return 1;
      }
      else
      {
      return fun(n / 10) + 1;
      }
      }
  • 4.上楼可以一步上一阶,也可以一步上两阶。设计一个递归算法,计算共有多少种不同的走法。
    • 设f(n)表示n阶楼梯的不同的走法数,显然f(1) = 1,f(2) = 2(两阶有一步一步走和两步走2种走法)。f(n - 1)表示n - 1阶楼梯的不不同走法数,f(n - 2)表示n - 2阶楼梯的不同的走法数,对于n阶楼梯,第1步上一阶有个f(n - 1)种走法,第1步上两阶有f(n - 2)种走法,则f(n) = f(n - 1) + f(n - 2)。对应的递归算法如下:
    • 答:
      int fun (int n)
      {
      if(n == 1 || n == 2)
      {
      return n;
      }
      else
      {
      return fun(n - 1) + fun (n - 2);
      }
      }
  • 5.设置一个递归算法,利用顺序串的基本运算求串s的逆串。
    • 经分析,求逆串的递归模型如下:
      f(s) = s 若s = Φ
      f(s) = Concat(f(SubStr(s, 2, StrLength(s) - 1)), SubStr(s, 1, 1)) 其他情况
    • 递归思想是:对于s="s1s2...sn"的串,假设"s2s3...sn"已求出其逆串即f(SubStr(s, 2, StrLength(s) -1)),再将s1(为SubStr(s, 1, 1))单个字符构成的串连接到最后即得到s的逆串。对应的递归算法如下
      #include "sqstring.cpp"
      SqString invert(SqString s)
      {
      SqString s1,
      s2;
      if(StrLength(s) > 0)
      {
      s1 = invert(SubStr(s, 2, StrLength(s) - 1));
      s2 = Concat(s1, SubStr(s, 1, 1));
      }
      else
      {
      StrCopy(s2, s);
      }
      return s2;
      }
  • 6.设有一个不带表头结点的单链表L,设计一个递归算法count(L)求以L为首结点指针的单链表的结点个数。
    • 对应的递归算法如下:
      int count(LinkNode *L)
      {
      if(L == NULL)
      {
      return 0;
      }
      else
      {
      return count(L -> next) + 1;
      }
      }
  • 7.设有一个不带表头结点的单链表L,设计两个递归算法,traverse(L)正向输出单链表L的所有结点值,traverseR(L)反向输出单链表L的所有结点值。
    • 答:对应的递归算法如下:
      void traverse(LinkNode *L)
      {
      if(L == NULL)
      {
      return;
      printf("%d", L -> data);
      traverse(L -> next);
      }
      }
      void traverseR(LinkNode *L)
      {
      if(L == NULL)
      {
      return;
      traverseR(L -> next);
      printf("%d", L -> data);
      }
      }
  • 8.设有一个不带表头结点的单链表L,设计两个递归算法,del(L, x)删除单链表L中第一个值为x的结点,delall(L, x)删除单链表L中所有值为x的结点。
    • 答:对应的递归算法如下
      void del(LinkNode *&L, ElemType x)
      {
      LinkNode *t;
      if(L == NULL)
      {
      return;
      }
      if(L -> data == x)
      {
      t = L;
      L = L -> next;
      free(t);
      }
      del(L -> next, x);
      }
      void delall(LinkNode *&L, ElemType x)
      {
      LinkNode *t
      if(L == NULLL)
      {
      return;
      }
      if(L -> data == x)
      {
      t = L;
      L = L -> next;
      free(t);
      }
      delall(L -> next, x);???
      }
  • 9.设有一个不带表头结点的单链表L,设计两个递归算法,maxnode(L)返回单链表L中最大结点值,minnode(L)返回单链表L中最小结点值。
    • 对应的递归算法如下:
      ElemType maxnode(LinkNode *L)
      {
      ElemType max;
      if(L -> next == NULL)
      {
      return L -> data;
      }
      max = maxnode(L -> next);
      if(max > L -> data)
      {
      return max;
      }
      else
      {
      retrun L -> data;
      }
      }
      ElemType minnode(LinkNode *L)
      {
      ElemType min;
      if(L -> next == NULL)
      {
      return L -> data;
      }
      min = minnode(L -> next);
      if(min > L -> data)
      {
      return L -> data;
      }
      else
      {
      return min;
      }
      }
  • 10.设计一个模式匹配算法,其中模板串t含有通配符‘ * ’,它可以和任意子串匹配。对于目标串s,求其中匹配模板t的一个子串的位置('*'不能出现在t的最开头和末尾)。
    • 答:采用BF模式匹配的思路,当是s[i]和t[i]比较,而t[j]为‘’,取出s中对应‘’的字符之后的所有字符构成的字符串,即SubStr(s, i + 2, s.lentgh - i - 1),其中i + 2是s中对应‘*’字符后面一个字符的逻辑序号。再取出t中‘ * ’字符后面的所有字符构成的字符串,即SubStr(t, j + 2, t.length - j - 1),递归对它们进行匹配,若返回值大于-1,表示匹配成功,返回i。否则返回-1,
      #include 'sqstring.cpp'
      findpat(SqString s, SqString t)
      {
      int i = 0,
      j = 0,
      k;
      while(i < s.length && j < t.length)
      {
      if(t.data[j] == '*')
      {
      k = findpat(SubStr(s, i + 2, s.length - i - 1), SubStr(t, j + 2, length - j - 1));
      j ++;
      if(k > -1)
      {
      return i - 1;
      }
      else
      {
      return -1;
      }
      }
      else if(s.data[i] == t.data[j])
      {
      i ++;
      j ++;
      }
      else
      {
      i = i - j + 1;
      j = 0;
      }
      }
      if(j > t.length)
      {
      return i - 1;
      }
      else
      {
      return -1;
      }
      }
参考:《数据结构教程(第5版)》    
如果你看完觉得这篇文章不错,帮我两件小事
  • 点个在看,让更多人也能看到这篇内容
  • 关注公众号前端应届生,持续为你推送精彩文章71fa70c57f4ad78b948b3062fb6941d7.png
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值