C - 链表的addLast函数的奇怪行为

时间:2011-07-08 11:18:06

标签: c pointers linked-list

我在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时。

我到目前为止已经发现它实际上是 虽然由于某种原因它不会被打印出来。例如,如果我在关闭函数List之前执行另一个addLast(list, 6);调用(当然在循环之外!),输出行Added something at last position...(在调用{{1}之后发生)实际上会显示addLast(l, 7);

那么,我做错了什么?

谢谢!

4 个答案:

答案 0 :(得分:4)

问题不在AddLast()只是你的displayList()功能:)。您在最后一个元素之前停止打印1个元素。

更改displayList()功能:

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

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

  printf(")");
}

此功能也可以打印空列表。

答案 1 :(得分:1)

您只是不打印列表的最后一项。

node->data为NULL时,您知道当前节点之后没有更多节点。但你需要在停止之前显示最后一个!!

您可以将支票修改为node != NULL来执行此操作。

答案 2 :(得分:1)

您的显示功能是错误的:在您的循环中,对于列表的最后一个元素,您有

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

你的循环不会显示它:

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

您可以像while (node != NULL) {

那样修复

答案 3 :(得分:1)

您的问题出在displayList ::

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

当node-&gt; next到达最后一项时,它将为null,因此不显示。