[英]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
,它將這個新創建的節點添加到由head
和end
指針定義的鏈表中。
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
進來的地方。當你開始初始化head
到ptr
,然后從不移動頭部時,你將始終記住列表的開頭位置。
你還有一個變量:
struct node *end = (struct node*) NULL;
你必須不斷更新每次添加,以便始終指向添加的最后一個元素...如果你關心。 如果你打算制作一個雙鏈表,通常是end
或last
或tail
指針。
我可以添加一個名字和年齡完全正常,但第二個我添加另一個名稱和年齡它覆蓋了前一個。
您的代碼不會覆蓋前一個節點,它會將其替換為新節點並泄漏您之前的節點。 (泄漏是你分配的一塊內存,然后丟失任何指針,以便你永遠不能解除分配。)這是創建一個新節點的行:
ptr = initnode(name, age);
如果ptr
是指向列表中第一個節點的指針,則應將新節點添加到列表的末尾,而不是將其分配給ptr
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.