【问题标题】:How could I write this function recursively?我怎么能递归地编写这个函数?
【发布时间】:2021-11-16 17:02:02
【问题描述】:

这是哈希表结构:

struct hash_table
{
  entry_t buckets[No_Buckets];
};

这是入口结构:

struct entry
{
  int key;       // holds the key
  char *value;   // holds the value
  entry_t *next; // points to the next entry (possibly NULL)
};

该函数的目的是返回哈希表的大小(它包含多少个 !NULL 条目),但我不确定我应该如何递归地编写它。

int hash_table_size(hash_table_t *ht)
{
  int counter = 0;
  for (int i = 0; i < No_Buckets; i++)
  {
    entry_t *current_entry = (ht->buckets[i]).next;
    if (current_entry != NULL)
      {
        counter++ ;
      }
  }
  return counter;
}

【问题讨论】:

  • 为什么你认为这个任务需要递归?我认为循环可以很好地完成工作,只要进行一些调整。
  • 您可以通过循环轻松替换if(..) ...,而无需递归。
  • @RefugnicEternium 仅用于学习目的,我认为此功能将是最简单的尝试:)。
  • 如何确定存储桶是否正在使用? (目前您只计算携带一连串后代的桶)
  • @davdavdav2 数组是固定大小的。条目永远不会为空。你如何检测到一个条目 in use

标签: c recursion struct hashtable


【解决方案1】:

为了回答您的问题,递归通常意味着当前活动的函数使用不同的参数调用自身。

所以,如果你想将上面的循环实现为递归函数,它会是这样的:

int countBuckets(struct entry *pEntry, int position)
{
     int count = 0;
     if (pEntry->next)
          ++count;
     if (++position < NoBuckets)
          count += countBuckets(++pEntry, position);
     return count;
}

此函数获取条目数组(因此是 *),检查第一个条目是否有后续条目,然后调用自身并包含下一个条目。

正如我在 cmets 中所说,“循环可以很好地完成工作”。 附带说明一下,传递条件是必要的,否则你会遇到“无限递归”,导致程序崩溃。

附带说明,如果您想计算链表的成员数,则代码需要更改如下:

struct hash_table
{
  entry_t *buckets;
};

int hash_table_size(hash_table_t *ht)
{
    entry_t *entry;
    int counter = 0;
    for (entry = ht->buckets; entry; entry->next)
        counter++ ;

    return counter;
}

或者,如果你真的想递归地做:

int countBuckets(entry_t *entry)
{
    int counter = 0;
    if (entry)
        counter += countBuckets(entry->next) + 1;

    return counter;
}

【讨论】:

  • 甚至可以压缩成if (entry) return 1 + countBuckets(entry-&gt;next); else return 0;
  • 确实如此,是的。或者,可能是return (entry) ? 1 + countBuckets(entry-&gt;next) : 0;。 (几乎)总是有改进的余地。 :)
  • 使用?: 有点混淆。实际上,我的意思是变量 countercountBuckets 中几乎没有任何作用
  • 是的,你是对的,@tstanisl。然而,与此同时,我曾经被教导,任何函数都应该,如果可能的话,只有一个出口点。这完全是个人风格的问题,真的。
猜你喜欢
  • 2021-10-06
  • 2014-01-07
  • 2012-07-01
  • 2017-08-19
  • 2022-11-11
  • 1970-01-01
  • 2017-03-23
  • 2016-03-07
  • 2019-09-10
相关资源
最近更新 更多