C - Странное поведение для функции addLast связанного списка - PullRequest
1 голос
/ 08 июля 2011

Я создаю структуру данных связанного списка в C. Однако я получаю странное поведение в своей реализации функции addLast. Кажется, что добавленный элемент не появляется до моего следующего вызова addLast. Мой код (я объясню через встроенные комментарии, как я думаю, что мой код работает):

Код помощника:

typedef struct LinkedList linkedlist;
typedef int ListElement;

struct LinkedList{
  ListElement data;
  linkedlist *next;
};

//Initializes a list;
void CreateList(linkedlist *list, ListElement contents){
  list->data = contents;
  list->next = NULL;
}

//Prints the items of the list, head first.
void displayList(linkedlist *list){
  printf("(%d", list->data);
  linkedlist *node = list->next;

  if(node == NULL){
  }
  else{
    while(node->next != NULL){
      printf(" %d", node->data);
      node = node->next;
    }
  }

  printf(")");
}

Код проблемы:

//Adds an element at the tail of the list
void addLast(linkedlist *list, ListElement forAdding){
  linkedlist *node = list;
  linkedlist *NewNode = (linkedlist *) malloc(sizeof(linkedlist));

  //Go to the last element in the list
  while(node->next != NULL){
    node = node->next;
  }

  //Prepare the node we will add
  NewNode->data = forAdding;
  NewNode->next = NULL;

  //Since node is pointing to the tail element, set its
  //next to the NewNode---the new tail
  node->next = NewNode;
}

//Special attention to this function!
void List(ListElement items[], linkedlist *list, int numItems){
  int i = 0;

  while(i < numItems){
    addLast(list, items[i]);
    printf("Before ");
    displayList(list);
    printf("\n");
    printf("Added %d", items[i]);
    displayList(list);
    printf("\n");
    i++;
  }
}

Основная функция:

int main(){
  linkedlist *l= (linkedlist *) malloc(sizeof(linkedlist));
  CreateList(l, 0);
  int a_list[5] = {1, 2, 3, 5, 6};
  List(a_list, l, sizeof(a_list)/sizeof(a_list[0]));
  printf("A list of five elements: %d", sizeof(a_list)/sizeof(a_list[0]));
  displayList(l);
  removeLast(l);
  addLast(l, 7);
  printf("\nAdded something at last position: ");
  displayList(l);
  printf("\n");
}

Для которого я получаю вывод:

Before (0)
Added 1(0)
Before (0)
Added 2(0 1)
Before (0 1)
Added 3(0 1 2)
Before (0 1 2)
Added 5(0 1 2 3)
Before (0 1 2 3)
Added 6(0 1 2 3 5)
A list of five elements: 5(0 1 2 3 5)
Added something at last position: (0 1 2 3 5 6)

Как видите, добавленный элемент появится только при моем следующем вызове addLast.

До сих пор я понял, что это на самом деле , хотя по какой-то причине он не будет напечатан. Если, например, я сделаю еще один вызов addLast(list, 6); непосредственно перед тем, как закрыть функцию List (но, конечно, вне цикла!), Строка вывода Added something at last position... (что происходит после вызова addLast(l, 7);, фактически отобразит * 1022). *.

Итак, что я делаю не так?

Спасибо!

Ответы [ 4 ]

4 голосов
/ 08 июля 2011

Проблема не в AddLast(), это просто ваша displayList() функция :).Вы прекращаете печать 1 элемента перед последним элементом.

Измените функцию displayList() следующим образом:

void displayList(linkedlist *list){
  printf("(");
  linkedlist *node = list;

  while(node != NULL){
    printf(" %d", node->data);
    node = node->next;
  }   

  printf(")");
}

Эта функция также может печатать пустые списки.

1 голос
/ 08 июля 2011

Ваша проблема в displayList ::

...
  while(node->next != NULL){
      printf(" %d", node->data);
      node = node->next;
...

Когда node-> next достигает последнего элемента, оно будет нулевым и, следовательно, не будет отображаться.

1 голос
/ 08 июля 2011

Ваша функция отображения ошибочна: в вашем цикле для вашего последнего элемента списка вы получили

node->next = NULL
node->data != NULL

Ваш цикл не будет отображать это:

while(node->next != NULL){
  printf(" %d", node->data);
  node = node->next;
}

Выможно исправить так while (node != NULL) {

1 голос
/ 08 июля 2011

Вы просто не печатаете последний элемент списка.

Когда node->data НЕДЕЙСТВИТЕЛЕН, вы знаете, что НЕТ БОЛЬШЕ узла после текущего. Но вам нужно отобразить последний до остановки!

Для этого вы можете изменить свой чек на node != NULL.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...