我是数据结构的新手。我正在创建一个链接列表程序。我创建了程序。但是不明白为什么insertattail不会将节点添加到链接列表中。
struct node {
int data;
struct node *next;
};
struct node *head=NULL;
int main( void ) {
insertAtHead(3);
insertAtHead(4);
insertAtHead(5);
insertAtHead(8);
insertAtTail(2);
display();
return 0;
}
void insertAtHead( int data ){
struct node *newNode;
newNode = (struct node *)malloc( sizeof(struct node) );
newNode->data = data;
newNode->next = NULL;
if( head == NULL ){
head = newNode;
} else {
newNode->next = head;
head = newNode;
}
}
void insertAtTail(int data){
struct node *newNode, *temp;
newNode = (struct node *)malloc( sizeof(struct node) );
newNode->data = data;
newNode->next = NULL;
if( head == NULL){
head = newNode;
} else {
temp = head;
while ( temp != NULL){
temp = temp->next;
}
temp = newNode;
}
}
void display(){
struct node *temp;
temp = head;
while ( temp != NULL)
{
printf("%d -> ", temp->data);
temp = temp->next;
}
printf("NULLn");
}
期望输出:8-> 5-> 4-> 3-> 2-> null
实际输出:8-> 5-> 4-> 3-> null
变量 temp
是函数的局部变量,该变量占据了列表的节点。
此循环之后
temp = head;
while (temp != NULL) {
temp = temp->next;
}
变量temp
设置为空。然后在此语句中
temp = newNode;
您正在更改变量本身所占据的内存。列表的节点没有更改。
更改以下方式
temp = head;
while (temp->next != NULL) {
temp = temp->next;
}
temp->next = newNode;
还要注意两个在使用之前宣布所有功能的两个功能。
例如
void insertAtHead( int data );
//...
int main( void )
{
//...
}
函数涉及全局变量head
也不是一个好主意。您应该重写函数,以使列表的头将作为参数传递给函数。
例如,在这种情况下,函数 insertAtHead
可以定义folloing方式
int insertAtHead( struct node **head, int data )
{
struct node *newNode = malloc( sizeof(struct node) );
int success = newNode != NULL;
if ( success )
{
newNode->data = data;
newNode->next = *head;
*head = newNode;
}
return success;
}
作为一个程序的结果,您可以通过在本地声明本地来获得几个列表。
这是一个指示的程序
#include <stdio.h>
#include <stdlib.h>
struct node {
int data;
struct node *next;
};
int insertAtHead( struct node **head, int data )
{
struct node *newNode = malloc( sizeof(struct node) );
int success = newNode != NULL;
if ( success )
{
newNode->data = data;
newNode->next = *head;
*head = newNode;
}
return success;
}
int insertAtTail( struct node **head, int data )
{
struct node *newNode = malloc( sizeof(struct node) );
int success = newNode != NULL;
if ( success )
{
newNode->data = data;
newNode->next = NULL;
while ( *head != NULL ) head = &( *head )->next;
*head = newNode;
}
return success;
}
void display( struct node *head )
{
for ( struct node *current = head; current != NULL; current = current->next )
{
printf("%d -> ", current->data);
}
puts( "NULL" );
}
int main(void)
{
struct node *head = NULL;
insertAtHead( &head, 3 );
insertAtHead( &head, 4 );
insertAtHead( &head, 5 );
insertAtHead( &head, 8 );
insertAtTail( &head, 2 );
display( head );
return 0;
}
其输出是
8 -> 5 -> 4 -> 3 -> 2 -> NULL
temp = head;
while ( temp != NULL) {
temp = temp->next;
}
temp = newNode;
重新分配temp
这里什么都不做。而是检查temp->next
是否为null并使用:
temp = head;
while (temp->next != NULL) {
temp = temp->next;
}
temp->next = newNode;
这样,您仍在更改head
,而不是temp
。
更改以下内容:
while (temp != NULL)
temp = temp->next;
}
temp = newNode;
:
while (temp->next != NULL) {
temp = temp->next;
}
temp->next = newNode;
由于您想做的是去旧节点,然后在执行此操作之后,指定旧的 last Node ,即> new 最后一个节点是newNode
。
live demo (请注意我如何在主方法之前移动您的方法的定义,以便它可以编译 - 或者,您可以在MAIN之前声明原型,并且仍然在您时保持定义。现在有它们(。
ps:我会抛出malloc的结果吗?否。