使用双指针在C中插入链表
Linked List Insertion in C using double pointer
嗨,我是学习链表的新手,我创建了这个示例程序,但它并没有填充所有列表,只有最后两个被填充(或者这些覆盖了第一个链接元素)
谁能帮我解决这个问题?
#include<stdio.h>
#include<stdlib.h>
struct node {
int data;
struct node *link;
};
void appendNode(int data, struct node **ptr) {
struct node *newnode = (struct node*)malloc(sizeof(struct node));
newnode->data = data;
newnode->link = NULL;
if(*ptr == NULL) {
*ptr = newnode;
} else {
while((*ptr)->link != NULL ) {
*ptr = (*ptr)->link;
}
(*ptr)->link = newnode;
}
}
void printList(struct node *node)
{
while (node != NULL)
{
printf(" %d ", node->data);
node = node->link;
}
}
int main() {
struct node *head = NULL ;
appendNode(23,&head);
appendNode(45,&head);
appendNode(32,&head);
appendNode(11,&head);
appendNode(98,&head);
printList(head);
}
Ir 打印
11 98
这里的问题是什么引起的?
替换:
while((*ptr)->link != NULL ) {
*ptr = (*ptr)->link;
}
(*ptr)->link = newnode;
与:
struct node* last = *ptr;
while (last->link) {
last = last->link;
}
last->link = newnode;
虽然将它提取到它自己的函数中可能会很好:
struct node* findLastNode(struct node* ptr) {
while (ptr->link) {
ptr = ptr->link;
}
return ptr;
}
然后,在appendNode
里面:
struct node* last = findLastNode(*ptr);
last->link = newnode;
你的问题是你在appendNode
[1]中用指针本身迭代。每次您将某些内容分配给 *ptr
时,都会更改列表地址,例如
*ptr = newnode;
...
*ptr = (*ptr)->link;
每次 *ptr
被分配 列表地址 都会改变(如 appendNode
和 main()
中所见)
你的列表操作是正确的,你需要做的就是使用临时指针遍历列表(iter
下面)
void appendNode (int data, struct node **ptr) {
struct node *newnode = malloc (sizeof *newnode),
*iter = *ptr;
if (!newnode) { /* VALIDATE every allocation */
perror ("malloc-newnode");
exit (EXIT_FAILURE);
}
newnode->data = data;
newnode->link = NULL;
if (iter == NULL) {
*ptr = newnode;
}
else {
while (iter->link != NULL) {
iter = iter->link;
}
iter->link = newnode;
}
}
(注意 使用与 sizeof
一起使用的解引用指针来设置类型大小。如果使用解引用指针来设置大小,则消除设置所需的实际类型时的任何错误。另外,如果你分配 - 你必须每次都验证 -
进行了该更改(以及对 printList
的以下更改)
void printList (struct node *node)
{
while (node != NULL)
{
printf(" %d ", node->data);
node = node->link;
}
putchar ('\n'); /* tidy up with newline */
}
您的列表工作得很好,例如
例子Use/Output
$ ./bin/lllast2
23 45 32 11 98
脚注:
1. 虽然不是错误,但 C 通常避免使用 camelCase
或 MixedCase
变量名,以支持所有 小写,同时保留大写 名称用于宏和常量。这是一个风格问题——因此完全取决于您,但不遵循它可能会导致在某些圈子中产生错误的第一印象。
嗨,我是学习链表的新手,我创建了这个示例程序,但它并没有填充所有列表,只有最后两个被填充(或者这些覆盖了第一个链接元素)
谁能帮我解决这个问题?
#include<stdio.h>
#include<stdlib.h>
struct node {
int data;
struct node *link;
};
void appendNode(int data, struct node **ptr) {
struct node *newnode = (struct node*)malloc(sizeof(struct node));
newnode->data = data;
newnode->link = NULL;
if(*ptr == NULL) {
*ptr = newnode;
} else {
while((*ptr)->link != NULL ) {
*ptr = (*ptr)->link;
}
(*ptr)->link = newnode;
}
}
void printList(struct node *node)
{
while (node != NULL)
{
printf(" %d ", node->data);
node = node->link;
}
}
int main() {
struct node *head = NULL ;
appendNode(23,&head);
appendNode(45,&head);
appendNode(32,&head);
appendNode(11,&head);
appendNode(98,&head);
printList(head);
}
Ir 打印
11 98
这里的问题是什么引起的?
替换:
while((*ptr)->link != NULL ) {
*ptr = (*ptr)->link;
}
(*ptr)->link = newnode;
与:
struct node* last = *ptr;
while (last->link) {
last = last->link;
}
last->link = newnode;
虽然将它提取到它自己的函数中可能会很好:
struct node* findLastNode(struct node* ptr) {
while (ptr->link) {
ptr = ptr->link;
}
return ptr;
}
然后,在appendNode
里面:
struct node* last = findLastNode(*ptr);
last->link = newnode;
你的问题是你在appendNode
[1]中用指针本身迭代。每次您将某些内容分配给 *ptr
时,都会更改列表地址,例如
*ptr = newnode;
...
*ptr = (*ptr)->link;
每次 *ptr
被分配 列表地址 都会改变(如 appendNode
和 main()
中所见)
你的列表操作是正确的,你需要做的就是使用临时指针遍历列表(iter
下面)
void appendNode (int data, struct node **ptr) {
struct node *newnode = malloc (sizeof *newnode),
*iter = *ptr;
if (!newnode) { /* VALIDATE every allocation */
perror ("malloc-newnode");
exit (EXIT_FAILURE);
}
newnode->data = data;
newnode->link = NULL;
if (iter == NULL) {
*ptr = newnode;
}
else {
while (iter->link != NULL) {
iter = iter->link;
}
iter->link = newnode;
}
}
(注意 使用与 sizeof
一起使用的解引用指针来设置类型大小。如果使用解引用指针来设置大小,则消除设置所需的实际类型时的任何错误。另外,如果你分配 - 你必须每次都验证 -
进行了该更改(以及对 printList
的以下更改)
void printList (struct node *node)
{
while (node != NULL)
{
printf(" %d ", node->data);
node = node->link;
}
putchar ('\n'); /* tidy up with newline */
}
您的列表工作得很好,例如
例子Use/Output
$ ./bin/lllast2
23 45 32 11 98
脚注:
1. 虽然不是错误,但 C 通常避免使用 camelCase
或 MixedCase
变量名,以支持所有 小写,同时保留大写 名称用于宏和常量。这是一个风格问题——因此完全取决于您,但不遵循它可能会导致在某些圈子中产生错误的第一印象。