问题
hey for some reason my linked list is printing in the reversed ordear for example if my input is 2->4->6 my output is 6->4->2
list* add_int_list(list* a,int b)
{
list *temp;
temp = (list*)malloc(sizeof(list*));
temp->next = NULL;
if (a->next == NULL)//insert to the first node
{
temp->data = b;
temp->next = a;
a = temp;
}
else
{
temp->data = b;
temp->next = a;
a = temp;//I think the problem is here, couldnt find how to fix
}
回答1:
For starters in this statement
temp = (list*)malloc(sizeof(list*));
^^^^^
there is allocated memory of the size equal to the size of pointer instead of the size of the node. You have to write either
temp = (list*)malloc(sizeof(list));
or
temp = (list*)malloc(sizeof( *temp));
This if statement
if (a->next == NULL)
can invoke undefined behavior because initially the list can be empty. So the pointer a
can be equal to NULL. That is there is used a null pointer to access memory.
There is no difference between these two code blocks after the if and else parts of the if-else statement
if (a->next == NULL)//insert to the first node
{
temp->data = b;
temp->next = a;
a = temp;
}
else
{
temp->data = b;
temp->next = a;
a = temp;//
}
That is the both code snippet try insert a new-node in the beginning of the list.
It is a general approach to insert a new node in a singly-linked one-sided list in its beginning. To append a node to such a list to its end is inefficient because the whole list must be traversed.
If you want to append a node to the end of a singly linked list then make it two-sided.
Here is a demonstrative program.
#include <stdio.h>
#include <stdlib.h>
typedef struct Node
{
int data;
struct Node *next;
} Node;
typedef struct List
{
Node *head;
Node *tail;
} List;
int push_front( List *list, int data )
{
Node *new_node = malloc( sizeof( Node ) );
int success = new_node != NULL;
if ( success )
{
new_node->data = data;
new_node->next = list->head;
list->head = new_node;
if ( list->tail == NULL ) list->tail = list->head;
}
return success;
}
int push_back( List *list, int data )
{
Node *new_node = malloc( sizeof( Node ) );
int success = new_node != NULL;
if ( success )
{
new_node->data = data;
new_node->next = NULL;
if ( list->tail == NULL )
{
list->head = list->tail = new_node;
}
else
{
list->tail = list->tail->next = new_node;
}
}
return success;
}
void output( const List *list )
{
for ( const Node *current = list->head; current != NULL; current = current->next )
{
printf( "%d -> ", current->data );
}
puts( "null" );
}
int main(void)
{
List list = { .head = NULL, .tail = NULL };
const int N = 10;
for ( int i = 0; i < N; i++ )
{
if ( i % 2 != 0 )
{
push_front( &list, i );
}
else
{
push_back( &list, i );
}
output( &list );
}
return 0;
}
Its output is
0 -> null
1 -> 0 -> null
1 -> 0 -> 2 -> null
3 -> 1 -> 0 -> 2 -> null
3 -> 1 -> 0 -> 2 -> 4 -> null
5 -> 3 -> 1 -> 0 -> 2 -> 4 -> null
5 -> 3 -> 1 -> 0 -> 2 -> 4 -> 6 -> null
7 -> 5 -> 3 -> 1 -> 0 -> 2 -> 4 -> 6 -> null
7 -> 5 -> 3 -> 1 -> 0 -> 2 -> 4 -> 6 -> 8 -> null
9 -> 7 -> 5 -> 3 -> 1 -> 0 -> 2 -> 4 -> 6 -> 8 -> null
In this demonstrative program even numbers are inserted in the end of the list using the function push_back
and odd numbers are inserted in the beginning of the list using the function push_front
.
If you C compiler does not support designated initializers then this declaration
List list = { .head = NULL, .tail = NULL };
can be changed the following way
List list = { NULL, NULL };
回答2:
The problem is that your code is appending the node to the front of the list in both cases. If you want to always append to the end of the list, you need to walk the list until the end and then add temp
there.
I wrote this code off-the-cuff, so take it as pseudo-code:
// Assuming this function returns the front (head) of the list.
list* append_element_to_list(list* a, int b)
{
list *newNode;
newNode = (list*)malloc(sizeof(list*));
newNode->data = b;
// Handle the case where `a` is NULL. This means
// no list was passed in, so the newly created node
// will be returned to start the list.
if (a == NULL)
{
return newNode;
}
// If we get this far, it means `a` contains at least
// one node. So walk the list until the end.
list *currentNode = a;
while (currentNode->next != NULL)
{
currentNode = currentNode->next;
}
// Once you reach the end of the list, set
// `newNode` as the last node.
currentNode->next = newNode;
// The front of the list hasn't changed, so return that.
return a;
}
回答3:
You have some mistakes in your code, I am making correction in your code, just changing what required. first I want to focus on main issue, before inserting at last of any list, you should iterate the complete list.
i = a; // to iterate
while(i->next != NULL)
{
i = i->next;
}
// Now i is last node of list a
i->next = temp;
Now the below code, I just check it on TurboC, I am using your function and inserting three values and then printing the list. Please see all the line comments:
#include <stdio.h>
#include <malloc.h>
typedef struct node{
int data;
struct node *next;
}list;
list* add_int_list(list* a,int b)
{
list *temp;
list *i;
temp = (list*)malloc(sizeof(list*));
temp->next = NULL;
temp->data = b;
if (a == NULL)//insert to the first node
{
//temp->data = b; - done above
//temp->next = a; no reason for this line
a = temp;
}
else
{
// temp->data = b; - done above
//temp->next = a; wrong logic
// a = temp;//I think the problem is here, couldnt find how to fix : Yes it is also wrong
//Here it required to iterate complete list and go to end
i = a; // to iterate
while(i->next != NULL)
{
i = i->next;
}
// Now i is last node of list a
i->next = temp;
}
return a;
}
void printList(list *root)
{
list *i;
if(root == NULL)
{
printf("List is empty");
}
else
{
i = root;
while(i != NULL){
printf("%d,",i->data);
i = i->next;
}
}
}
int main()
{
list *root = NULL;
clrscr();
root = add_int_list(root, 3);
root = add_int_list(root, 4);
root = add_int_list(root, 5);
printList(root);
return 0;
}
来源:https://stackoverflow.com/questions/61116597/fix-for-a-reversed-link