【问题标题】:Circular linked list going in infinite loop循环链表无限循环
【发布时间】:2011-10-06 15:13:36
【问题描述】:

我应该做一个可以使用循环链表进行多项式加法/减法/乘法/求值的程序。

我的乘法代码进入了无限循环,我已经在它发生的地方标记了一条注释(用 printf 语句检测到,已删除)。

list* poly_mul(list *p1, list *p2) {
  term tmp;
  list *result = malloc(sizeof(list));
  memcpy(result, p1, sizeof(list));
  node *b = p2->head;
  node *r = result->head;
  do {
    do {
      tmp.exp = r->data.exp + b->data.exp;
      tmp.coeff = r->data.coeff * b->data.coeff;
      unsigned int add_term = 1;
      node *c = result->head;
      do {
        if(c->data.exp == tmp.exp) {
          c->data.coeff += tmp.coeff;
          add_term = 0;
          break;
        }
        c = c->next;
        //Here it goes in infinite loop
      } while(c != result->head);
      if(add_term)
        node_add(result, &tmp);
      b = b->next;
    } while(b != p2->head);
    r = r->next;
  } while(r != result->head);
  return result;
}

使用的结构在这里:

typedef struct {
  int exp;
  int coeff;
} term;

typedef struct node {
  term data;
  struct node *next;
} node;

typedef struct {
  node *head;
  node *tail;
  unsigned int count;
} list;

这是 main 中的代码:

void main() {
  list p1, p2, *p3;
  p1.count = p2.count = 0;
  poly_create(&p1);
  p3 = poly_mul(&p1, &p2);
  poly_print(p3);
}

void poly_create(list *l) {
  int i, n;
  printf("\nEnter number of terms in the polynomial: ");
  scanf("%d", &n);
  for(i = 1; i <= n; i++) {
    printf("\nEnter details for term %d: ", i);
    term_append(l);
}

void node_add(list *l, term *t) {
  node *tmp = malloc(sizeof(node));
  memcpy(&tmp->data, t, sizeof(term));
  if(l->count == 0) {
    l->head = tmp;
    l->tail = tmp;
    tmp->next = tmp;
  }
  else {
    l->tail->next = tmp;
    tmp->next = l->head;
    l->tail = tmp;    
  }
  l->count++;
}

void term_append(list *l) {
  term t;
 enter:
  printf("\nEnter term as <coefficient>,<exponent>: ");
  scanf("%d,%d", &t.coeff, &t.exp);
  if(!t.coeff) {
    printf("\nCoefficient is zero, reenter term");
    goto enter;
  }
  if(l->count >= 1) {
    node *i = l->head;
    do {
      if(i->data.exp == t.exp) {
        printf("\nExponent %d was already entered, reenter term", t.exp);
        goto enter;
      }
      i = i->next;
    } while(i != l->head);
    node_add(l, &t);
  }
  else
    node_add(l, &t);
}

请帮我解决这个问题,过去三个小时我一直在尝试解决这个问题。

【问题讨论】:

  • 您是否尝试过在进入循环之前打印出您的列表?
  • 是每次都发生还是在某些输入下发生?
  • @jv42 是的,打印了列表并且打印完美。我也在打印函数中使用了 head 和 next 指针。
  • @lostyzd 它每次都会发生
  • 可能与您在循环期间添加节点有关?您是否在每一轮都打印了列表?我知道这有点乏味。

标签: c linked-list circular-list


【解决方案1】:

为什么会进入无限循环?您可以通过使用调试器并单步执行代码来找出答案。只需在适当的地方放置一个断点,您应该可以自己找到它。很可能,您的链表中有一个循环。

您可以使用两个指针检查链表中的循环。第一个(尾部)指向列表的开头。第二个(head)指向列表的第二个元素。通过将 head 和 tail 都加一来循环直到 head 超过最后一个元素(我有那些指向 NULL,而不是 head)。如果在任何时候tail > head,你有一个循环。

【讨论】:

    【解决方案2】:

    如果您在每次迭代中printf("%d",(int) c); 会发生什么?我怀疑 result->head 指向的节点指向链表的成员,但不在链表本身中。

    潜在测试:将int seen 添加到列表的每个成员,并在每个成员上增加它,因为您循环给定数量的节点(过高的值,例如 INT_MAX),当循环停止时,查看结果是否->头->看到> 0:

    typedef struct node {
      term data;
      struct node *next;
      // to be removed later
      int seen;
    } node;
    
    // place this before you get the infinite loop
    unsigned int i = 1;
    c->seen = 0;
    do
    {
        c = c->next;
        c->seen = i;
    // replace INT_MAX with some number which is greater than the maximum list length
    } while(++i <= INT_MAX);
    // this should be roughly equal to i (might be off by 1).
    // I'll bet it isn't though!
    printf("result->head->seen = %d", result->head->seen);
    

    【讨论】:

    • 卡住了,可能是循环到 INT_MAX!
    • 尝试其他任意数字,它
    【解决方案3】:

    一个可能的原因:您从未创建过 p2。您是否在 main 函数中缺少这样的一行:

    poly_create(&p2);
    

    ?

    【讨论】:

    • 不,我有那行。我没有在这里包含添加代码,添加完美。
    • 嗯,好的,可以在问题中说出来,这将有助于缩小错误范围。
    猜你喜欢
    • 1970-01-01
    • 2013-03-19
    • 2012-05-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-04
    • 1970-01-01
    • 1970-01-01
    • 2019-08-06
    相关资源
    最近更新 更多