数据结构与算法之递归调用 -- 实验六

数据结构与算法之递归调用 – 实验六

实验名称

实验六 递归调用


实验目的

  1. 了解递归的基本概念;

  2. 了解递归调用的实现原理;

  3. 了解递归算法的设计;

  4. 利用循环或栈将递归算法转换成非递归算法。


验证题

    1. 利用递归函数,求正整数n的阶乘:
#include <iostream>
using namespace std;

// 本程序用递归算法求n的阶乘

int counter = 0;

int fac(int n)
{
    
    
	counter++; // 断点
	cout << "第" << counter << "次调用:n=" << n << endl;

	if (n == 0 || n == 1)
		return 1;
	else
		return n * fac(n - 1);
}

int main()
{
    
    
	cout << "结果:fac(5)=" << fac(5) << endl;
	return 0;
}

运行程序,理解递归调用的过程。

在断点标示处设置断点,查看每次递归调用时 countern 的值。

同时,观察系统栈的变化过程,加深对递归调用的理解:


    1. 根据大课课件,完成汉诺塔问题的完整程序,并设定盘子的数目分别为3和6,调试程序,理解程序的执行过程。

设计题

  1. 请使用循环结构,将n的阶乘的递归算法转换成非递归算法。

    #include <iostream>
    using namespace std;
    
    int fac(int n)
    {
          
          
      int sum = 1;
      if (n == 0 || n == 1)
        return 1;
      else
        for (size_t i = n; i > 0; i--)
        {
          
          
          sum *= i;
        }
      return sum;
    }
    
    int main()
    {
          
          
      cout << fac(5) << endl;
      return 0;
    }
    
    
  2. 已知 A[n] 为整数数组,编写一个递归算法求 n 个元素的平均值。

提示: Avg(n) = ( Avg(n-1) * (n-1) + A[n-1] ) / n

// NueXini
#include <iostream>

double getAverage(size_t *num, size_t n)
{
    
    
  if (n == 0)
    return num[n];
  else
    return (num[n - 1] + (n - 1) * getAverage(num, n - 1)) / (n);
}

int main()
{
    
    
  size_t num[] = {
    
    1, 2, 3, 4};
  std::cout << getAverage(num, 4) << std::endl;
  return 0;
}

思考题

  1. 已知Ackermann函数定义,写出计算Ack(m,n)的递归算法。

// NueXini
#include <iostream>

int Ack(int m, int n)
{
    
    
  if (m == 0)
    return (n + 1);
  else if (m != 0 && n == 0)
    return (Ack(m - 1, 1));
  else
    return (Ack(m - 1, Ack(m, n - 1)));
}

int main()
{
    
    
  std::cout << Ack(3, 6) << std::endl;
  return 0;
}
  1. 已知单链表中存储的都是整型数据,实现下列递归算法。

(1) 递归求单链表中最大整数,p指向首元结点;

​ int GetMax(LinkNode* p);

// NueXini
#include <iostream>

typedef int ElemType;
typedef struct NNode
{
    
    
  ElemType data;
  struct NNode *next;
} Node;

void InitList(Node *&L)
{
    
    
  L->next = NULL;
}

void TraverseList(Node *L)
{
    
    
  Node *p = L->next;
  while (p)
  {
    
    
    std::cout << p->data << "  ";
    p = p->next;
  }
  std::cout << std::endl;
}

bool ListInsert(Node *L, int pos, ElemType item)
{
    
    
  Node *p = L;
  int i = 0;
  while (p && i != pos - 1)
  {
    
    
    p = p->next;
    i++;
  }
  if (p == NULL)
  {
    
    
    return false;
  }
  Node *t = new Node;
  t->data = item;
  t->next = p->next;
  p->next = t;
  return true;
}

ElemType getMax(Node *p)
{
    
    
  int max;
  if (p->next == NULL)
    return p->data;
  else
  {
    
    
    max = getMax(p->next);
    return p->data >= max ? p->data : max;
  }
}

int main()
{
    
    
  Node *a = new Node();
  InitList(a);
  for (size_t i = 0; i < 10; i++)
  {
    
    
    if (!ListInsert(a, i + 1, i))
    {
    
    
      std::cout << "false" << std::endl;
    }
  }
  TraverseList(a);
  std::cout << getMax(a) << std::endl;
  return 0;
}

(2) 递归求单链表结点个数,L指向头结点;

​ int GetLength(LinkNode* L);

// NueXini
#include <iostream>

typedef int ElemType;
typedef struct NNode
{
    
    
  ElemType data;
  struct NNode *next;
} Node;

void InitList(Node *&L)
{
    
    
  L->next = NULL;
}

void TraverseList(Node *L)
{
    
    
  Node *p = L->next;
  while (p)
  {
    
    
    std::cout << p->data << "  ";
    p = p->next;
  }
  std::cout << std::endl;
}

bool ListInsert(Node *L, int pos, ElemType item)
{
    
    
  Node *p = L;
  int i = 0;
  while (p && i != pos - 1)
  {
    
    
    p = p->next;
    i++;
  }
  if (p == NULL)
  {
    
    
    return false;
  }
  Node *t = new Node;
  t->data = item;
  t->next = p->next;
  p->next = t;
  return true;
}

ElemType GetLength(Node *p)
{
    
    
  static size_t sum;
  if (p->next != NULL)
  {
    
    
    sum += 1;
    return GetLength(p->next);
  }
  else
  {
    
    
    return sum;
  }
}

int main()
{
    
    
  Node *a = new Node();
  InitList(a);
  for (size_t i = 0; i < 10; i++)
  {
    
    
    if (!ListInsert(a, i + 1, i))
    {
    
    
      std::cout << "false" << std::endl;
    }
  }
  TraverseList(a);
  std::cout << GetLength(a) << std::endl;
  return 0;
}

(3) 递归逆置单链表,p指向首元结点,返回逆置后的首元结点地址。

​ LinkNode* ListReverse_recursive(LinkNode* p);

// NueXini
#include <iostream>

typedef int ElemType;
typedef struct NNode
{
    
    
  ElemType data;
  struct NNode *next;
} Node;

void InitList(Node *&L)
{
    
    
  L->next = NULL;
}

void TraverseList(Node *L)
{
    
    
  Node *p = L->next;
  while (p)
  {
    
    
    std::cout << p->data << "  ";
    p = p->next;
  }
  std::cout << std::endl;
}

bool ListInsert(Node *L, int pos, ElemType item)
{
    
    
  Node *p = L;
  int i = 0;
  while (p && i != pos - 1)
  {
    
    
    p = p->next;
    i++;
  }
  if (p == NULL)
  {
    
    
    return false;
  }
  Node *t = new Node;
  t->data = item;
  t->next = p->next;
  p->next = t;
  return true;
}

ElemType GetLength(Node *p)
{
    
    
  static size_t sum;
  if (p->next != NULL)
  {
    
    
    sum += 1;
    return GetLength(p->next);
  }
  else
  {
    
    
    return sum;
  }
}

Node *ListReverse_recursive(Node *p)
{
    
    
  if (p->next == NULL)
  {
    
    
    return p;
  }
  Node *q = ListReverse_recursive(p->next);
  p->next->next = p;
  p->next = NULL;
  return q;
}

int main()
{
    
    
  Node *a = new Node();
  InitList(a);
  for (size_t i = 1; i < 11; i++)
  {
    
    
    if (!ListInsert(a, i, i))
    {
    
    
      std::cout << "false" << std::endl;
    }
  }
  TraverseList(a);
  TraverseList(ListReverse_recursive(a));
  return 0;
}


enjoy it ~

猜你喜欢

转载自blog.csdn.net/a924282761/article/details/127274427
今日推荐