簡體   English   中英

單鏈表 - C.

[英]Singly Linked List - C

我對單鏈表有一個非常快速的問題,我在其他問題中找不到答案。

這是我的代碼:

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

void add(int data);
void printList();

struct node
{
    int data;
    struct node * link;
};

struct node * head = NULL;

main()
{
    char c; 

    while ((c = getchar()) != 'q')
    {
        if (c == 'a')
        {
            int temp;

            printf("data: ");
            scanf("%d", &temp);

            add(temp);
        }

        if (c == 'p')
            printList();
    }
}

void add(int data)
{
    struct node * temp = (struct node *) malloc(sizeof(struct node));

    if (temp == NULL)
        fprintf(stderr, "error");

    temp->link = head;
    temp->data = data;
    head = temp;
}

void printList()
{
    struct node * temp = (struct node *) malloc(sizeof(struct node));

    if (temp == NULL)
        fprintf(stderr, "error");

    temp = head;

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

現在,我被告知我需要在我的add函數中創建一個函數或一個場景,如果正在創建一個新列表,它會做一些不同的事情。 換句話說,當列表為空,並且第一個元素被添加到它時,它需要與填充列表在前面接收另一個節點時不同地完成。 我在網上找到了這樣的代碼示例:

# // Adding a Node at the Beginning of the List  
#   
# void addBeg(int num)  
# {  
#    struct Node *temp;  
#   
#    temp=(struct Node *)malloc(sizeof(struct Node));  
#    temp->Data = num;  
#   
#    if (Head == NULL)  
#    {  
#       //List is Empty  
#       Head=temp;  
#       Head->Next=NULL;  
#    }  
#    else  
#    {  
#       temp->Next=Head;  
#       Head=temp;  
#    }  
# } 

正如您將注意到的,如果列表為空,則填充頭節點。

我的代碼工作正常,但我想知道我是否忽略了處理空頭情況的問題。

非常感謝!

add()函數沒有任何根本錯誤。 head == NULL的情況不需要特殊處理。

正如其他人注意到的那樣,您的錯誤檢查不正確,因為您需要從函數返回,以防malloc失敗。 就像它的情況一樣,當tempNULL時, add()函數會繼續嘗試分配給*temp

您通過這種特殊處理展示的代碼是虛假的。 head == NULL時,該代碼中的else子句運行得非常好。

您可以選擇在每次使用時檢查您的指針是否為空,或者如果您對頭節點的處理方式不同,則可以假設它不為空。

良好的舉止假設您應該始終檢查它,但如果您不檢查並且不取消引用空指針,那么您的代碼無論如何都會起作用。

因為您將始終運行該行(添加節點時)

head = temp;

添加節點后,頭節點中永遠不會有NULL引用。 這是因為您在上面驗證(temp!= null)temp不是空指針。

現在,在搜索節點時,在訪問任何(不)指向的字段之前檢查頭節點是否為空是一個非常好的主意。 也許這就是“特殊條件”中的含義,並且這些注釋與這種情況混淆在一起,通常不需要。

如果你考慮addBeg if branch:

if (Head == NULL)  
{  
   Head=temp;  
   Head->Next=NULL;  
}  
else  
{  
   Head=temp;  
   temp->Next=Head;  
}  

你看到你正在為head分配temp然后設置next指針。 另一方面,您的實施是:

temp->link = head;
temp->data = data;
head = temp;

如果你跳過data部分(並且head = temp在兩種情況下都存在),你會很容易看到它等同於第一個,因為

temp->link = head;

是相同的:

if (Head == NULL)  
{  
   Head->Next=NULL;  
}  
else  
{  
   temp->Next=Head;  
}  

暫無
暫無

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

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