簡體   English   中英

我的功能沒有記住鏈接列表的開頭

[英]My function doesn't memorize the head of linked list

我必須做一個具有很多功能的鏈表程序,例如刪除,添加和修改號碼。

在我的代碼中,當我在函數中選擇數字1時,在此之后,當我想顯示所有數字時,我將head放在參數中,但是我在Visual Studio中看到函數的參數沒有任何內容。 為了在函數Displaynbr中的參數中傳遞鏈接列表的Displaynbr ,我該怎么辦

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

struct Mynbr
{
    int nbr;
    struct Mynbr* next;
} typedef Mynbr;

void Menu();
void choiceMenu(int choice, Mynbr* first);
Mynbr* Addnumber(Mynbr* first);
void Displaynbr(Mynbr* first);

int main(void)
{
    Mynbr* head = NULL;
    int choice = 0;

    while (choice!=5)
    {
        Menu();
        printf("Your choice : "); scanf("%d", &choice);
        choiceMenu(choice, head);
    }
    system("PAUSE");
    return 0;
}

void Menu()
{
    printf("\n1.Add number to the list\n");
    printf("2.Delete number from the list\n");
    printf("3.Search number in the list\n");
    printf("4.Display all the numbers from the list\n");
    printf("5.Exit\n");
}

void choiceMenu(int choice, Mynbr* first)
{
    switch (choice)
    {
    case 1:
        Addnumber(first);
        break;
    case 2:
        break;
    case 3:
        break;
    case 4:
        Displaynbr(first);
        break;
    case 5:
        break;
    }
}

Mynbr* Addnumber(Mynbr* first)
{
    printf("\n===Function to add a number===\n");
    Mynbr* head_nbr = first;
    if (!head_nbr)
    {
        head_nbr = (Mynbr*)malloc(sizeof(Mynbr));
        printf("Enter a number :"); scanf("%d", &(head_nbr->nbr));
        head_nbr->next = NULL;
    }
    return head_nbr;
}

void Displaynbr(Mynbr* first)
{
    printf("\n===Function to display number===\n");
    Mynbr* curr = first;
    if (curr->next)
    {
        printf("The number is : %d", curr->nbr);
        Displaynbr(first->next);
    }
}

您離它不是很遠,但是忘記了一條基本規則: 當您更改函數中參數的值時,調用者的值保持不變

因此, AddNumber (幾乎)正確地返回了列表頭地址的新值,但是choiceMenu立即將其丟棄。

因此,這里有一些修復:

AddNumber應該能夠將一個數字添加到一個空列表或非空列表中(注意:當前它會導致一個LIFO):

Mynbr* Addnumber(Mynbr* first){
    printf("\n===Function to add a number===\n");
    Mynbr* head_nbr = first;
    head_nbr = (Mynbr*)malloc(sizeof(Mynbr));
    printf("Enter a number :"); scanf("%d", &(head_nbr->nbr));
    head_nbr->next = first;   // just link to initial head, be it null or not

    return head_nbr;
}

choiceMenu不應丟棄新的標頭-您可以像對AddNumber一樣將其返回給調用方,也可以使用雙倍間接AddNumber

void choiceMenu(int choice, Mynbr** first){
    switch (choice){
case 1:
    *first = Addnumber(*first);
    break;

case 2:
    break;
case 3:
    break;
case 4:
    Displaynbr(*first);
    break;
case 5:
    break;
    }
}

(不要忘記更改初始聲明並調用它: choiceMenu(choice, &head)

最后但並非最不重要的一點是, DisplayNumber錯誤地測試了curr->next而不是curr

void Displaynbr(Mynbr* first){
    printf("\n===Function to display number===\n");
    Mynbr* curr = first;
    if (curr) {
        printf("The number is : %d", curr->nbr);
        Displaynbr(first->next);
    }
}

但這仍然顯示===用於顯示列表中每個值的數字===的功能 最好在這里使用簡單的迭代而不是遞歸:

void Displaynbr(Mynbr* first){
    printf("\n===Function to display number===\n");
    Mynbr* curr = first;
    while (curr) {
        printf("The number is : %d\n", curr->nbr);
        curr = curr->next;
    }
}

或使用for循環:

void Displaynbr(Mynbr* first){
    printf("\n===Function to display number===\n");
    Mynbr* curr;
    for (curr=first; curr != NULL; curr=curr->next) {
        printf("The number is : %d\n", curr->nbr);
    }
}

通過刪除無用的局部變量,遞歸版本甚至可以更加簡潔(感謝@sokkyoku的提示):

void Displaynbr(Mynbr* first){
    printf("\n===Function to display number===\n");
    if (first) {
        printf("The number is : %d", first->nbr);
        Displaynbr(first->next);
    }
}

如果要更改AddNumber以具有FIFO列表,則需要在列表末尾添加新元素。 代碼變為:

Mynbr* Addnumber(Mynbr* first){
    printf("\n===Function to add a number===\n");
    Mynbr* head_nbr = malloc(sizeof(Mynbr));
    printf("Enter a number :"); scanf("%d", &(head_nbr->nbr));
    head_nbr->next = NULL;
    if (first == NULL) first = head_nbr;
    else {
        Mynbr* last = first;
        while (last->next != NULL) last = last->next;
        last->next = head_nbr;
    }
    return first;
}

但是在那種情況下,保留指向列表最后一個元素的指針而不是瀏覽列表來查找它會更有效。

該函數具有一個原型

Mynbr* Addnumber(Mynbr* first)

它由Addnumber(first)調用。 通常,由於函數的變化, first指針指向的值將被更新。 但是,第一個指針本身不會被更新。 即指針將保持為NULL。 如果以前為NULL。

要解決此問題,您需要像這樣在main中調用該函數

first = Addnumber(first);

另外,您的AddNumber函數需要固定。 當列表的第二個或更大的元素時,您沒有添加數字。

Mynbr* Addnumber(Mynbr* first){
  printf("\n===Function to add a number===\n");
  Mynbr* head_nbr;
  head_nbr = malloc(sizeof(Mynbr));
  printf("Enter a number :"); scanf("%d", &(head_nbr->nbr));
  if (!first)
  {
    head_nbr->next = NULL;
  }
  else
  {
    head_nbr->next = first;
  }
  return head_nbr;
}

該函數根據變量head_nbr建議添加到列表的head_nbr 要最后添加,您將必須進行適當的修改。

暫無
暫無

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

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