Круговой связанный список, идущий в бесконечном цикле - PullRequest
2 голосов
/ 06 октября 2011

Я должен создать программу, которая может выполнять сложение / вычитание / умножение / оценку за полином, используя круговой связанный список.

Мой код умножения находится в бесконечном цикле, и я пометил комментарий, где это происходит (обнаружено с помощью операторов 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;

А это код в основном:

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);
}

Пожалуйста, найдите мне решение этой проблемы, я пытался решить эту проблему в течение последних трех часов.

Ответы [ 3 ]

2 голосов
/ 06 октября 2011

Что произойдет, если вы 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);
2 голосов
/ 06 октября 2011

Почему это входит в бесконечный цикл? Вы можете узнать это с помощью отладчика и пошагового выполнения кода. Просто установите точку останова в соответствующем месте, и вы сможете найти ее самостоятельно. По всей вероятности, в вашем связанном списке есть петля.

Вы можете проверить наличие петель в связанном списке с помощью двух указателей. Первый (хвост) указывает на начало вашего списка. Второй (голова) указывает на второй элемент вашего списка. Цикл до головы проходит мимо последнего элемента (я указал на NULL, а не на голову), увеличивая голову и хвост на единицу. Если в любой точке хвост> голова, у вас есть петля.

0 голосов
/ 06 октября 2011

Одна из возможных причин: вы никогда не создаете p2. Вам не хватает такой строки в вашей функции main:

poly_create(&p2);

...