【问题标题】:Problem in implementing a recursive function实现递归函数的问题
【发布时间】:2019-07-25 03:07:16
【问题描述】:

对于家庭作业,我得到了这段代码,其中包含实现递归函数的指令,该函数在 main 列表中的下一个节点上调用自身,除非当前节点为 NULL 或当前节点的值等于“目标”

我最近的尝试是下面代码的围栏部分。我可以让它打印 0,但这不是整个列表。我不确定自己做错了什么,因为我对链表和节点没有太多经验。

typedef struct node {
  struct node* next;
  unsigned short index;
  char* value;
} node;

node* create_node(unsigned short index, char* value) {
  node* n = malloc(sizeof(node));
  n->value = value;
  n->index = index;
  n->next = NULL;
  return n;
}

node* create_nodes(char* values[], unsigned short index, unsigned short num_values) {
  if(num_values == 0) {
    return NULL;
  }

  node* n = create_node(index, values[0]);

  n->next = create_nodes(values + 1, index + 1, num_values - 1);
  return n;
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
node* find_match(node* cur, char* target) {
  if(cur == NULL){
    return NULL;
  }
    if(cur->value != NULL){
      node* result = create_node(cur->index, cur->value);
      result->next = find_match(cur->next, cur->value);
    }else{
    return find_match(cur->next, cur->value);
    }
  }
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

int main() {
  char* values[] = {
    "foo", // 0
    "bar", // 1
    "baz", // 2
    "duh", // 3
    "dunk", // 4
    "derp" // 5
  };

  node* head = create_nodes(values, 0, 6);

  node* target = find_match(head, "dunk");

  printf("%d\n", target->index);

  return 0;
}

没有给出错误消息,除了我已经“修复”的先前分段错误,但我认为它应该打印整个列表。

【问题讨论】:

  • 关于明确问题的提示:如果cur->value != NULL 为真,find_match 会返回什么?
  • 然后仔细检查递归调用find_match时传递的参数。 (但等等!还有更多……)
  • 我想我不希望 find_match 返回任何东西,直到它通过列表完成,在这种情况下,当 cur->value 最终达到 NULL 时,它会转到 else 语句
  • 如果你声明一个函数返回一个值,它必须返回一个值。否则你会有未定义的行为。想想你的函数,如果函数实际上没有返回任何东西,node* target = find_match(head, "dunk"); 将如何工作?
  • find_match()curr->value 不是 NULl 时不会返回,这会导致返回垃圾。对于调试段错误,我推荐使用 Valgrind。

标签: c recursion linked-list


【解决方案1】:

您可以一次插入一个元素并使用循环发送每个元素,因为您知道数组的大小。然后您只需对代码进行少量更改。

struct linkList {
       int data;
       linkList* next;
  }node;

 node create(int val){
       node tmp;
       tmp = (node)malloc(sizeof(struct linkList));
       tmp->data = val;
       return tmp;
  }
 node* insertNodeAtHead(linkList* llist,int data) {
        node tmp;
        tmp = create(data);
        tmp->next = llist;
        return tmp;
     }

然后您可以使用您的 Key 进行搜索,就像打印 List 中的所有元素一样

void print(linkList* head) {
     while(head !=NULL){
     printf("%d\n",head->data); // check here is this your key or Not 
     head = head->next;
   }
 } 

但是这个问题是已知的,在发布任何问题之前,请确保您尝试在 Google 中进行足够的搜索!!。希望您能理解并以自己的方式实现它。

【讨论】:

    【解决方案2】:

    代码中存在一些问题。

    1. 问题出在findmatch 函数中。在此根据问题陈述,如果目标节点存在,则应返回它,否则应返回 NULL。这可以通过以下方式实现。

      node* find_match(node* cur, char* target) {
        if(cur == NULL){
          return NULL;
        }
          if(strcmp(cur->value,target) ==0){
              return (cur);
          }else if (cur->value != NULL){
              return find_match(cur->next, target);
          }
          else {
              return NULL;
          }
        }
      

    附加点

    1. create_node 函数中,您直接复制字符串指针。这可能适用于这种特定情况,但理想情况下,您应该为 value 字段单独分配内存。

      node* create_node(unsigned short index, char* value) {
        node* n = malloc(sizeof(node));
        n->value = strdup(value);
        n->index = index;
        n->next = NULL;
        return n;
      }
      
    2. 打印值时,应检查findmatch返回的值是否为NULL

      node* target = find_match(head, "dunk");
      if (target != NULL) {
        printf("%d\n", target->index);
      }
      else {
        printf (" Not found\n");
      }          
      

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-01-27
      • 1970-01-01
      • 2020-03-29
      • 1970-01-01
      • 2017-11-26
      相关资源
      最近更新 更多