C列表的实现

时间:2015-08-28 16:56:54

标签: c list pointers

我使用以下代码来实现我自己的列表版本,以帮助我理解和掌握指针的概念。但是这个代码很麻烦,我无法弄清楚错误是什么?

#include <stdio.h>

typedef struct node
{
    int n;
    struct node* next;
} node;

int main(void)
{
    int i;
    node item;
    item.n = 0;
    item.next = NULL;
    node* list = &item;
    node* new_node = NULL;
    node* old_node = &item;

    while (1 == 1)
    {
        // get int from user
        scanf("%i", &i);

        if (i < 0)
        {
            break;
        }
        else
        {
            // Create new node
            node new_item;
            new_node = &new_item;

            // Set the value of new node
            new_node->n = i;
            new_node->next = NULL;

            // Point old node to new node
            old_node->next = new_node;

            // Swap nodes
            old_node = new_node;
            new_node = NULL;
        }

    }

    // Print the list
    node* pointer = list;
    int count = 1;
    while (pointer->next != NULL)
    {
        printf("Item %i %p: %i\n", count, pointer, pointer->n);
        pointer = pointer->next;
        getchar();
    }
}

我正在使用上面的代码为列表创建自己的实现。问题是当我尝试打印出列表时,它会进入一个无限循环。任何人都可以指出我哪里出错了吗?

5 个答案:

答案 0 :(得分:1)

您似乎在尝试构建前向链接列表,同时保留插入顺序。代码中最明显的问题是:

  • 无限的循环条件
  • 在列表中使用自动变量来表示动态节点。

这两个都是必须解决的。前者通过简单地修改while循环来解决(a)检查scanf执行的结果(你应该总是做),以及(b)检查范围i。因此,

while (scanf("%i", &i) == 1 && i >= 0)
{
     ... use i here
}

关于第二个问题,这会变得更加麻烦。使用内存管理函数mallocfree的动态分配可能是有序的。执行此操作的实现使用指针指针来使前向链接无关紧要,如下所示:

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

typedef struct node
{
    int n;
    struct node* next;
} node;

int main()
{
    // builds the list. uses a pointer-to-pointer that holds
    //  the address of the next pointer to populate wih a
    //  dynamic node allocation. initially it holds the
    //  addres of our list head pointer.

    node *list = NULL;  // list head pointer
    node **pp = &list;
    int i;

    while (scanf("%i", &i) == 1 && i >= 0)
    {
        *pp = malloc(sizeof **pp);
        if (*pp == NULL)
        {
            perror("Failed to allocate node");
            exit(EXIT_FAILURE);
        }

        (*pp)->n = i;
        pp = &(*pp)->next;
    }
    *pp = NULL; // terminates the list with NULL next value

    // print the list
    const node* pointer = list;
    for (i=1; pointer; ++i)
    {
        printf("Item %i %p: %i\n", i, pointer, pointer->n);
        pointer = pointer->next;
    }

    // free the list
    while (list)
    {
        void *victim = list;
        list = list->next;
        free(victim);
    }

    return EXIT_SUCCESS;
}

示例输入

1 3 2 4 3 5 -1

示例输出

Item 1 0x100300000: 1
Item 2 0x100300010: 3
Item 3 0x100300020: 2
Item 4 0x100300030: 4
Item 5 0x100300040: 3
Item 6 0x100300050: 5

答案 1 :(得分:0)

这里还有更多要说的,但从根本上说:你只分配了一个node,它就在堆栈上。它在else子句中声明。由于只分配了其中一个,因此您将其下一个指针设置为有效地指向自身。因此,无限循环。

答案 2 :(得分:0)

#include<stdio.h>

#include<stdlib.h>

#include<malloc.h>

struct node
{

int info;

struct node *next;

};

struct node *first,*temp,*start;

int item;
struct node *insertatend(struct node *,int);

main()
{
       char ch;   
    first=NULL;
     while(ch=='y'){
           printf("Enter the item");
           scanf("%d",&item);
           first=insertatend(first,item);
        printf("Do you want to continue press y");
        scanf("%c",&ch);
}

/*Insert item in linked list at the end*/
struct node *insertatend(struct node *first,int x)
{
   start=first;
   struct node *new;
   new=(struct node *)malloc(sizeof(struct node));   
   new->info=x;
   new->next=NULL;
        if(first==NULL)
            {
            first=new;  
                }
            else
            {
                temp=first;
                while(temp->next!=NULL)
                    {
                    temp=temp->next;    
                    }
                    temp->next=new;

            }

 return(first);
}

或者如果你想和你的鳕鱼一起使用,那么使用while(1)而不是1 == 1,因为它始终是真的,你永远不会从循环中出来。  希望它能为你带来

答案 3 :(得分:0)

因为你可以使用指向malloc&amp;的指针。免费我推荐以下: 这应该满足你的问题。如果你有任何问题,请告诉我。

#include <stdio.h>
#include <malloc.h>

typedef struct Node
{
  int a;
  Node *next;
}NODEType;

NODEType *head = NULL;

int printtraverse()
{
  NODEType *n = head;
  while ( n !=NULL ) {
    printf ( "item = %d \n", n->a );
    n = n->next;
  }
}

int main ()
{
  int t=0;
  NODEType *curr=NULL;
  while (1) {
    scanf("%d",&t);

  NODEType *n = (NODEType *) malloc (sizeof (NODEType));
  n->a = t;
  n->next = NULL;

  if ( head == NULL )
  {
     head = n;
     curr = n;
  } else {
     curr->next = n;
     curr = n;
  }   

 if ( t == -1 )
    printtraverse();

 }

return 0;
}

答案 4 :(得分:0)

这段代码有效!!好像我malloc()free()做了这个伎俩。谢谢大家的帮助!请指出此代码中的任何缺陷。

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

typedef struct node
{
    int n;
    struct node* next;
} node;

int main(void)
{
    int i;
    // pointer to start of list
    node* list = NULL;
    // nodes to keep track
    node* old_node = NULL;
    node* new_node = NULL;

    while (scanf("%i", &i) == 1 && i >= 0)
    {
        if (old_node == NULL)
        {
            // create new node
            new_node = (node*) malloc(sizeof(node));
            new_node->n = i;
            new_node->next = NULL;

            // point list to this node
            list = new_node;

            // point old node to this node
            old_node = new_node;
        }
        else
        {
            // create new node
            new_node = (node*) malloc(sizeof(node));
            new_node->n = i;
            new_node->next = NULL;

            // point old nodes pointer to this node
            old_node->next = new_node;

            // set the new node as old node
            old_node = new_node;
        }
    }

    // print the list
    node* pointer = list;
    int count = 1;
    while (pointer != NULL)
    {
        printf("Node %i : %i\n", count, pointer->n);
        free(pointer);
        pointer = pointer->next;
        count++;
    }
}