簡體   English   中英

鏈接列表中的全局指針

[英]Global Pointer in Linked List

因此,我遇到了這個問題,希望您能幫助我解決這個問題。 我有此鏈接列表,要求用戶在其中輸入數據。 當我僅使用一個集合但希望此鏈接列表與多個集合一起使用時,它適用,但是我已聲明頭節點為全局集合,但我不知道如何安排它。 問題是,當我在一組中輸入數據時,它也將輸入保留在第二組中。

這是鏈表的結構:

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;
} 

最后是Add函數:

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;
}

正如Oli Charlesworth所說,您需要將要操作的列表作為參數傳遞給處理列表的每個函數。 一會兒,我將向您展示如何做,但首先讓我對您的代碼中的一些問題發表評論。

  • 您的代碼看起來不整潔,因為您沒有從輸入中分離集合的邏輯(添加數字,檢查數字是否已在集合中)(與scanf一切)。 相反,您可以使用Add函數以很大的一部分來實現所有功能。

  • 另外,為什么將x作為參數傳遞給Add 永遠不會讀取它(至少不會被scanf覆蓋之后)。 這實際上應該是一個局部變量。 set ,您現在可以將其用作局部變量。

  • 您已經將typedef'fed的struct nodelist ,這是合法的,但是有點令人困惑。 (節點不是列表。)

好的,繼續您的問題:您應該為每個新列表創建一個start = NULL 然后,您將該start傳遞給所有列表函數。 但是您在這里必須要小心:大多數功能(例如打印或檢查列表中是否有數字)都不要更改start的值。 您必須對附加函數進行更改,因此應將&start傳遞給該函數,即struct node **

因為這有點令人困惑,所以您可以使用另一種解決方案:創建一個表示列表的結構,為該列表編寫一個創建函數,然后對該結構的指針進行操作。

這是一個示例實現:

#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函數中添加元素,然后添加它們。

  • 由於列表的句柄是一個結構,因此可以通過向該結構添加新字段來輕松擴展列表接口。 例如,您可能想保留節點數或一個指示節點是否已排序的標志。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM