2014-01-05 90 views
0

所以我有这样的问题,我希望你能帮帮我吧。我有这个链表,用户被要求输入数据。它适用于当我只使用一个集合,但我希望这个链表使用多于1个集合但我已经将头节点声明为全局的时候,我不知道如何安排它。问题是,当我在一个集合中输入数据时,它也保留了第二集合的输入。全局指针链表

这是链表的结构:

struct node//initializing a linked list 
{ 
    int info; 
    struct node*link; 
}*start; 

这是我建立了我的链接列表:

list* createList() 
{ 
    struct node*set; 
    set=(struct node*)malloc(sizeof(struct node)); 
    if(start==NULL) 
    { 
     set->link=NULL; 
     start=set; 
    } 
    return set; 
} 

终于这是新增功能:

list* Add(list* set,int x) 
{ 
    struct node *tempnode; 
    if(start==NULL) 
    { 
     printf("Memory Allocation failed. Goodbye!"); 
    exit(EXIT_FAILURE); 
    } 
    set=start; 
    printf("Please enter an input: \n"); 
    scanf("%d",&x); 
    while(1) 
    { 
     while(x==set->info) 
     { 
      printf("Error! Please enter another integer: \n"); 
      scanf("%d",&x); 
      set=start; 
     } 
     if(set->link!=NULL) 
     set=set->link; 
     else 
      break; 
    } 
    tempnode=(struct node*)malloc(sizeof(struct node)); 
    tempnode->info=x; 
    tempnode->link=NULL; 
    set->link=tempnode; 
    printf("%d was created successfully!\n",x); 
    return set; 
} 
+3

那么,目前对全局变量进行操作的每个函数都需要修改,以便对参数进行操作。 –

+0

是的,但你能给我一些关于如何改变它们的提示吗? – user3141471

回答

1

奥利查尔斯沃斯已经评论说,你需要通过你想操作的列表作为每个参数函数处理一个列表。我会在一秒之内告诉你如何,但让我先评论一下你的代码的一些问题。

  • 你的代码看起来乱糟糟的,因为你没有在 集的逻辑从 输入分离(加号,查号是否已在集)(一切与scanf做)。相反你Add功能 实现一切在一个大块。

  • 另外,为什么你通过x作为参数Add?它永远不会被读取 (至少在被scanf覆盖之后)。这应该是真的 是一个局部变量。 set也是一样,此时您将此变量用作本地变量 。

  • 您已经打字输入struct nodelist,这是合法的, 但有点混淆。 (A节点不在名单。)

好了,以后你的问题:你应该为每一个新的列表创建start = NULL。然后您将该start传递给所有列表函数。但是您必须小心:大多数功能(如打印或检查数字是否在列表中)不会更改start的值。你的附加功能必须改变它,所以你应该通过&start,即struct node **这样的功能。

因为这是一个有点混乱,你可以使用其他的解决方案:创建一个代表列表的结构,编写该列表创建者函数,然后在该结构的指针operatoe。

下面是一个示例实现:

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

typedef struct Set Set; 
typedef struct Node Node; 

struct Node { 
    int info; 
    Node *next; 
}; 

struct Set { 
    Node *head; 
}; 

Set *set_create() 
{ 
    Set *set = malloc(sizeof(*set)); 

    // enforce set != NULL 
    set->head = NULL; 
    return set; 
} 

void set_delete(Set *set) 
{ 
    Node *node = set->head; 

    while (node) { 
     Node *next = node->next; 
     free(node); 
     node = next; 
    } 
} 

int set_contains(const Set *set, int x) 
{ 
    const Node *node = set->head; 

    while (node) { 
     if (node->info == x) return 1; 
     node = node->next; 
    } 

    return 0; 
} 

void set_print(const Set *set) 
{ 
    const Node *node = set->head; 

    printf("{"); 
    while (node) { 
     if (node != set->head) printf(", "); 
     printf("%d", node->info); 
     node = node->next; 
    } 
    printf("}\n"); 
} 

Node *set_add(Set *set, int x) 
{ 
    Node *node; 

    if (set_contains(set, x)) return NULL; 

    node = malloc(sizeof(*node)); 
    // enforce node != NULL 

    node->info = x; 
    node->next = NULL; 

    if (set->head == NULL) { 
     set->head = node; 
    } else { 
     Node *iter = set->head; 

     while (iter->next) iter = iter->next; 
     iter->next = node; 
    } 

    return node; 
} 

int main() 
{ 
    Set *one = set_create(); 
    Set *two = set_create(); 

    set_add(one, 1); 
    set_add(one, 1); 
    set_add(one, 2); 
    set_add(one, 3); 
    set_add(one, 5); 
    set_add(one, 1); 
    set_add(one, 5); 

    set_add(two, 1); 
    set_add(two, 2); 
    set_add(two, 4); 

    set_print(one); 
    set_print(two); 

    set_delete(one); 
    set_delete(two); 

    return 0; 
} 

有几件事情需要注意:

  • 的代码被分裂为完成特定任务的小功能。他们可能会互相呼叫,并且总是清楚所做的事情。

  • 构造函数set_create创建一个指向空列表的指针。该指针是句柄,您应该将其作为第一个参数传递给所有列表函数。

  • 与你的代码一样,添加整数的函数检查列表是否已经包含整数。然而,由于set_add函数不处理来自用户的输入,因此它表示节点是否真的被添加或不在其返回值中:如果整数已经在列表中,则为NULL,否则指向新节点的指针。

  • 当您创建列表并向其中添加整数时,您将使用malloc分配内存。这意味着,您还需要具有使用free再次释放内存的功能,以避免内存泄漏。

  • 示例代码将一些硬连线整数添加到列表中;它不处理用户输入。您可以轻松编写一个循环来在您的main函数中添加元素,然后添加它们。

  • 由于列表的句柄是一个结构体,因此可以通过向该结构体添加新字段来轻松扩展列表接口。例如,您可能希望保留一个节点数或一个指示节点是否已排序的标志。

+0

哇,惊人的答案! –