链接列表查询

时间:2013-12-03 09:21:47

标签: c data-structures

我有这个单链表:

#include <stdio.h>
#include <stdlib.h>
struct list_el {
   int val;
   struct list_el * next;
};

typedef struct list_el item;

int main() {
   item * curr, * head;
   int i, num_nodes;

   head = NULL;
   printf("Enter the number of nodes to be created: ");
   scanf("%d", &num_nodes);
   for(i=1;i<=num_nodes;i++) {
      curr = (item *)malloc(sizeof(item));
      printf("\n Enter the value :");
      scanf("%d", &curr->val);
      curr->next  = head;
      head = curr;
   }

   curr = head;

   while(curr) {
      printf("%d --> ", curr->val);
      curr = curr->next ;
   }
   getch();
   return 0;
}

行urr = head是什么;意思? 此外,在打印时,如果反向打印链接列表。为什么会这样?我认为这是因为我们将最后一个节点作为curr分配上述语句?如果是,那么curr-&gt;接下来的工作如何(curr)循环?

2 个答案:

答案 0 :(得分:3)

按要求提问:

  

curr = head;是什么意思?

这意味着获取指针变量head中保存的地址并将其存储在指针变量curr中。它与任何其他类型的复制按值没有区别,例如int a=1, b; b=a;

  

(它)反向打印链表。为什么会这样?

当您添加每个新项目时,该新项目将成为列表头部。因此,如果您按特定顺序输入数字, last 将是列表中的第一个,第一个将是最后一个。这种类型的结构通常称为LIFO(后进先出)。


如果您希望列表实际上是按照输入的顺序而不扫描到每个新插入的列表末尾,这是一种方法(和imho,效率最高):

#include <stdio.h>
#include <stdlib.h>

struct list_el
{
    int val;
    struct list_el * next;
};
typedef struct list_el item;

int main()
{
    item *curr, *head = NULL, **pp = &head;
    int i, num_nodes;

    printf("Enter the number of nodes to be created: ");
    scanf("%d", &num_nodes);

    for(i=1;i<=num_nodes;i++)
    {
        *pp =  malloc(sizeof(**pp)); // note: don't cast malloc() in C
        if (*pp == NULL)
        {
            perror("Failed to allocate node");
            exit(EXIT_FAILURE);
        }

        printf("\n Enter the value :");
        scanf("%d", &(*pp)->val);
        pp = &(*pp)->next;
    }

    // terminate the list
    *pp = NULL;

    // walk the list
    curr = head;
    while(curr)
    {
        printf("%d --> ", curr->val);
        curr = curr->next ;
    }
    getch();
    return 0;
}

如何运作

指针指针pp用于始终保存将接收下一个新节点分配的指针的地址。最初它以head指针变量的地址开头。在插入每个新节点时,pp将加载该添加节点的next成员的地址。当循环结束时,它将指向列表中的 last next指针,因此我们将其设置为NULL以终止,然后我们就完成了。

请注意,使用此算法,每次迭代都需要进行特殊的if (first-node)检查 。头指针自然填充添加的第一个节点(如果添加了 no 节点,则设置为NULL)。

最后,我留下了大部分(缺少)错误检查让你解决,虽然我不得不添加malloc()结果检查,从习惯的力量,如果没有别的。您应该检查每个库调用的成功,特别是scanf()调用

<强>输入

Enter the number of nodes to be created: 5

 Enter the value :1

 Enter the value :2

 Enter the value :3

 Enter the value :4

 Enter the value :5

<强>输出

1 --> 2 --> 3 --> 4 --> 5 -->

答案 1 :(得分:1)

curr = head表示您的curr指针将指向与head指针相同的节点。然后使用curr作为迭代器并遍历列表中的项目(在while循环中)。

它反向打印,因为在这些行的列表开头添加了项目:

curr->next  = head;
head = curr;

编辑:更改将项目添加到列表中的方式,以便将它们添加到列表的末尾:

 item *tempPointer = NULL;
 for(i=1;i<=num_nodes;i++) {
      curr = (item *)calloc(sizeof(item));         
      printf("\n Enter the value :");
      scanf("%d", &curr->val);
      if (i == 1) 
        head = curr;
      else {     
        tempPointer ->next  = curr;
      }      

      tempPointer = curr;
   }