簡體   English   中英

在C程序中打印鏈接列表

[英]Printing a linked list in C program

我看到一些關於如何打印鏈表的帖子,但是沒有一個對我有幫助,所以我決定發布我自己的代碼。 這是問題所在:

我可以添加一個名字和年齡完全正常,但第二個我添加另一個名稱和年齡它覆蓋了前一個。

所以,如果我輸入:

馬特和21,然后查爾斯和34.它只會輸出查爾斯和34.如何輸出它輸出一切? 提前感謝您的幫助! :)

這是我的代碼:

#include<stdlib.h>
#include<stdio.h>
#include<malloc.h>
#include<conio.h>
#include<string.h>
#include<ctype.h>
#define pause system ("pause")

// prototype variables
struct node * initnode(char*, int);
void printnode(struct node*);

struct node{
    char name[20];
    int age;
    struct node *next;
};

struct node *head = (struct node*) NULL;
struct node *end = (struct node*) NULL;

struct node* initnode(char *name, int age){
    struct node *ptr;
    ptr = (struct node*) calloc(3, sizeof(struct node));
    if(ptr == NULL) 
        return (struct node*) NULL;
    else {
        strcpy(ptr->name, name);
        ptr->age = age;
        return ptr;
    }
}

void printnode(struct node *ptr) {
    printf("Name -> %s\n", ptr->name);
    printf("Age -> %d\n", ptr->age);
}


main() {
    char name[20];
    int age, choice = 1;
    struct node *ptr;
    while(choice != 3){
        system("cls");
        printf("1. Add a name\n");
        printf("2. List nodes\n");
        printf("3. Exit");
        printf("\nEnter Menu Selection: ");
        scanf("%d", &choice);
        switch(choice) {
        case 1: printf("\nEnter a name: ");
            scanf("%s", name);
            printf("Enter age: ");
            scanf("%d", &age);
            ptr = initnode(name, age);
            break;
        case 2: if(ptr == NULL) {
                printf("Name %s not found\n", name);
            } else 
                printnode(ptr);
            pause;
            break;
        case 3: exit(3);
        default: printf("Invalid Entry");
        }// end of switch


    }// end of main

}

哦,我知道一些“#include”可能沒用。 我一整天都在添加和刪除代碼。

只是一個翻拍者:

ptr = (struct node*) calloc(3, sizeof(struct node));

是錯誤的,因為你正在分配3 * sizeof(struct node) ,它應該是

ptr = (struct node*) calloc(1, sizeof(struct node));

你的代碼遺漏了很多東西。 您沒有將您創建的節點鏈接到任何鏈接列表。 在整個代碼中你沒有使用next 您必須在此代碼上進行更多工作。

問題不僅來自鏈表的打印。 問題來自如何創建鏈表

我可以向你推薦一個鏈表的模板,它可以幫助你開發這樣的程序。 此模板包含用於處理鏈表的函數和宏

  • 添加到頭部的鏈表
  • 添加到尾部的鏈表
  • 從鏈接列表中刪除...

您可以從此鏈接獲取鏈接列表模板(list.h)

以下鏈接包含如何使用它的示例

請參閱上面鏈接中的這一段

只需很少的修改(刪除列表項的硬件預取),我們也可以在我們的應用程序中使用此列表。 此處提供此文件的可用版本供下載。

雖然您已經定義了可以創建鏈接列表的head指針和end指針,但實際上並沒有使用它們來存儲新信息。 創建新節點並將其存儲在ptr變量中后,實際上並未將其存儲在列表中。

我建議添加另一個方法addnode ,它將這個新創建的節點添加到由headend指針定義的鏈表中。

void addnode(struct node *ptr) {
    if (end == NULL) {
        head = ptr;
        end = ptr;
    }
    else {
        end = end->next = ptr;
    }
}

從廣義上講,我們檢查列表中是否有任何項目; 如果沒有,列表的開頭和結尾都將由同一個節點表示:列表中唯一的一個節點! 否則,我們讓當前結束后的節點成為要添加的節點,然后將我們的全局end指針移動到現在的最后一個節點。

這允許我們維護一個以上節點的鏈(列表中的條目)。 然后,當打印整個列表時,我們必須遵循整個鏈,從第一個節點( head )到最后一個節點。 我們可以通過一個簡單的循環來做到這一點:我們不是簡單地在main()維護的臨時ptr變量上調用printnode() main() ,而是編寫:

struct node *current = head;
while (current != end) {
    printnode(current);
    current = current->next;
}

這一行在這里:

ptr = initnode(name, age);

這就是為什么你總是覆蓋名稱/年齡,因為你聲明了一個名為ptr的本地節點,每次添加一個值時,你都會用下一個節點覆蓋該節點。

看到struct node *next; 節點結構中的元素? 您需要指向創建的下一個節點,以便擁有多個節點,類似於:

ptr->next = initnode(name, age);

第一個節點有鏈接列表的特殊情況,你的第一個節點ptr是空的,所以當你的列表長度是0時,你需要從init_node()設置ptr ,下次你需要設置ptr ' next元素,然后你需要更新ptr,以便它是當前節點:

ptr = ptr->next;

當然這樣做會導致你“松散”列表的開頭。 這就是你的head進來的地方。當你開始初始化headptr ,然后從不移動頭部時,你將始終記住列表的開頭位置。

你還有一個變量:

struct node *end = (struct node*) NULL;

你必須不斷更新每次添加,以便始終指向添加的最后一個元素...如果你關心。 如果你打算制作一個雙鏈表,通常是endlasttail指針。

我可以添加一個名字和年齡完全正常,但第二個我添加另一個名稱和年齡它覆蓋了前一個。

您的代碼不會覆蓋前一個節點,它會將其替換為新節點並泄漏您之前的節點。 (泄漏是你分配的一塊內存,然后丟失任何指針,以便你永遠不能解除分配。)這是創建一個新節點的行:

ptr = initnode(name, age);

如果ptr是指向列表中第一個節點的指針,則應將新節點添加到列表的末尾,而不是將其分配給ptr

暫無
暫無

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

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