Linked list reversal program is not working [closed] - c

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 years ago.
Improve this question
I am not able to identify any error in my program.
But when i run it,it is taking the inputs infinitely.At first i thought there must be some issues with the pointer assignments but everything seems fine.
The program is just taking inputs infinitely.
The reversing function is defined by rev().It doesn't take any parameters bcoz
head is defined globally.
#include <stdio.h>
struct node
{
int n;
struct node *next;
};
struct node *head;
//void beg(int);
//void nth(int,int);
//void delbe();
//void del(int);
void rev ();
int main()
{
int i, s, x, y, z, l;
i = 0;
struct node* temp;
struct node* temp1;
struct node* cur;
head = NULL;
scanf("%d", &s);
while (i < s) {
scanf("%d", &x);
if (head == NULL) {
temp = (struct node*)malloc(sizeof(struct node));
temp->n = x;
temp->next = NULL;
head = temp;
temp1 = head;
}
else {
temp = (struct node*)malloc(sizeof(struct node));
temp->n = x;
temp->next = NULL;
temp1->next = temp;
temp1 = temp1->next; //Assigning the next node.i.e. NULL value
}
i = i + 1;
}
cur = head;
printf("Before\n");
while (cur != NULL) {
printf("%d\n", cur->n);
cur = cur->next;
}
rev();
printf("After\n");
cur = head;
while (cur != NULL) {
printf("%d\n", cur->n);
cur = cur->next;
}
return 0;
}
void rev()
{
struct node* prev;
struct node* temp;
struct node* cur;
cur = head;
temp = cur;
while (temp != NULL) {
if (cur == head) {
prev = NULL;
cur->next = prev;
}
else {
cur = temp->next;
prev = temp;
temp = temp->next;
cur->next = prev;
if (temp == NULL) {
head = cur;
}
}
}
}

You have an infinite loop in this while loop
while (temp != NULL)
{
if (cur == head)
{
prev = NULL;
cur->next = prev;
}
//..
because cur is still equal to head after the if statement. So the control always is passed to this if statement within the loop.
The simplest way to reverse the list is to form a new list inserting nodes of the original list in the new list.
For example
void rev()
{
if ( head != NULL && head->next != NULL )
{
struct node *new_head = NULL;
while ( head != NULL )
{
struct node *current = head;
head = head->next;
current->next = new_head;
new_head = current;
}
head = new_head;
}
}

Related

Partitioning a linked list around a given value and keeping the original order

#include <stdio.h>
#include <stdlib.h>
struct _listNode{
int item;
struct _listNode* next;
};
typedef struct _listNode ListNode;
void printList(ListNode *head);
void deleteList(ListNode **ptrHead);
void triPartition(ListNode** head, int pivot);
int main()
{
ListNode *head = NULL, *temp;
int i = 0;
int pivot = 0;
scanf("%d",&pivot);
while (scanf("%d", &i)){
if (head == NULL){
head = (ListNode*) malloc(sizeof(ListNode));
temp = head;
}
else{
temp->next = (ListNode*) malloc(sizeof(ListNode));
temp = temp->next;
}
temp->item = i;
}
temp->next = NULL;
triPartition(&head, pivot);
printList(head);
deleteList(&head);
return 0;
}
void printList(ListNode *head){
while(head !=NULL){
printf("%d ",head->item);
head = head->next;
}
printf("\n");
}
void deleteList(ListNode **ptrHead){
ListNode *cur = *ptrHead;
ListNode *temp;
while (cur!= NULL) {
temp=cur->next;
free(cur);
cur=temp;
}
*ptrHead=NULL;
}
void triPartition(ListNode** head, int pivot){
ListNode *cur = *head;
ListNode *nextnode = NULL;
ListNode *pre = NULL;
ListNode *temp = NULL;
while (cur != NULL) {
nextnode = cur->next;
temp = nextnode;
printList(head);
if (cur->item > pivot){
while (temp->next != NULL){
temp = temp->next;
}
temp->next = cur;
cur->next = NULL;
pre = cur;
cur = nextnode;
nextnode = cur->next;
head = cur;
temp = NULL;
printList(head);
}
if (cur->item = pivot){
pre = cur;
head = cur;
cur = cur->next;
nextnode = nextnode->next;
printList(head);
}
if (cur->item < pivot){
pre->next=nextnode;
cur->next = pre;
pre = cur;
head = cur;
cur = nextnode;
nextnode = nextnode->next;
printList(head);
}
}
}
Example input
5
8 1 5 5 5 7 2 5 a
Expected output
2 1 5 5 5 5 8 7
im tryna reassign the head to the next node in the original list after moving the first node to the end
but somehow the item in the next node gets changed
and somehow the list gets shorter
i dont get what is wrong w the assigning of the head which results to this.
and i also dont get why i cant use
*head = cur
It was trivial to replace head with *head in the body of triPartition() but that left with a cycle in linked list. Looked at it for a while but I found it hard to reason about the algorithm because you have 4 variables and the pointers interact. After looking for a it a while, I figured you can look at the linked list this way:
a-> b-> c->
^ *head ^ left ^ cur
*head pointers to the first element of the the list, it may be different than what we were passed in so we do need a double pointer here. Elements from *head till and including left are smaller than the pivot. Elements from left->next to cur are pivot nodes followed by nodes larger than the pivot. This implementation reverses the order or pivots, you can fix that after the fact, or maintain a right pointer at the boundary between pivot and larger nodes.
I wrote a function createList() to create a list as it's much easier to test a non-interactive program.
#include <stdio.h>
#include <stdlib.h>
typedef struct ListNode {
int item;
struct ListNode *next;
} ListNode;
ListNode *createList(unsigned n, int *items) {
ListNode *head = malloc(n * sizeof(*head));
for(unsigned i = 0; i < n; i++) {
head[i].item = items[i];
head[i].next = i + 1 < n ? &head[i+1] : NULL;
}
return head;
}
void printList(ListNode *head){
for(; head; head = head->next) {
printf("%d ", head->item);
}
printf("\n");
}
void triPartition(ListNode **head, int pivot) {
ListNode *left = NULL;
for(ListNode *cur = *head; cur->next; ) {
int op = cur->next->item < pivot ? -1 : cur->next->item == pivot ? 0 : 1;
if(op <= 0) {
if(!left) {
left = cur->next;
cur->next = cur->next->next;
left->next = *head;
*head = left;
continue;
}
ListNode *tmp = left->next;
left->next = cur->next;
cur->next = cur->next->next;
left->next->next = tmp;
if(op < 0)
left = left->next;
} else {
cur = cur->next;
}
}
}
int main() {
ListNode *head = createList(8, (int []) {8, 1, 5, 5, 5, 7, 2, 5});
printList(head);
triPartition(&head, 5);
printList(head);
return 0;
}
and here the output of the above program:
8 1 5 5 5 7 2 5
1 2 5 5 5 5 8 7

Bubble Sort on Linked List Shortening List

typedef struct Node{
int data;
struct Node* next;
}Node;
Node* initNode(){
Node* newN = malloc(sizeof(Node));
newN->data = rand() % (1000 -0);
newN->next = NULL;
}
void addNodes(int amount, Node* first){
Node* cur = first;
while(cur->next != NULL){
cur = cur->next;
}
for(int i = 0; i <= amount; i++){
cur->next = initNode();
cur = cur->next;
}
}
void printNodes(Node* first){
Node* cur = first;
int loopC = 0;
while(cur->next != NULL){
printf("%d-", cur->data);
loopC++;
cur = cur->next;
}
}
beginning of areas causing problem
I think that it is something wrong with the sort or swap functions causing the shortening of the linked list, not sure though.
void swap(Node* prev, Node* cur, Node* first){
Node* next = cur->next;
if(next==NULL){return;}
Node* nextO = next->next;
cur->next = nextO;
if(prev != NULL){prev->next = next;}
else{first = next;}
next->next = cur;
}
void bubbleSort(Node* first){
int switchC = -1;
while(switchC != 0){
switchC = 0;
Node* cur = first;
Node* prev = NULL;
Node* next = NULL;
while(cur->next != NULL){
next = cur->next;
if(next->data <= cur->data){
swap(prev, cur, first);
switchC++;
}
prev = cur;
cur = next;
}
}
}
end of areas causing problem
void main(){
Node* first = initNode();
addNodes(10, first);
printNodes(first);
bubbleSort(first);
printNodes(first);
}
inputed linked list: Node 0: value:383-Node 1: value:886-Node 2: value:777-Node 3: value:915-Node 4: value:793-Node 5: value:335-Node 6: value:386-Node 7: value:492-Node 8: value:649-Node 9: value:421-Node 10: value:362
Outputed Linked List: Node 0: value:383-Node 1: value:386-Node 2: value:421-Node 3: value:492-Node 4: value:649-Node 5: value:777-Node 6: value:793-Node 7: value:886
I don't see why you need a prev pointer in your bubbleSort function.
Also, you don't have to change pointers in your swap function. Since the size of the list won't change, you can merely swap the data field.
Be careful no to squeeze your code this much. It's hard to follow.
Start with a known data (such as the vector 100,99,...,89 below).
Will be much easier to debug.
Here's a possible fix with minimum changes to your code:
#include <stdio.h>
#include <stdlib.h>
typedef struct Node{
int data;
struct Node* next;
}Node;
int count = 100;
Node* initNode(){
Node* newN = malloc(sizeof(Node));
newN->data = count--;
newN->next = NULL;
}
void addNodes(int amount, Node* first){
Node* cur = first;
while(cur->next != NULL){
cur = cur->next;
}
for(int i = 0; i <= amount; i++){
cur->next = initNode();
cur = cur->next;
}
}
void printNodes(Node* first){
Node* cur = first;
int loopC = 0;
while(cur != NULL){
printf("%d-", cur->data);
loopC++;
cur = cur->next;
}
printf("\n");
}
void swap(Node* node1, Node* node2)
{
int tmp = node2->data;
node2->data = node1->data;
node1->data = tmp;
}
void bubbleSort(Node* first)
{
int switchC = -1;
while(switchC != 0) {
switchC = 0;
Node* cur = first;
Node* next = NULL;
while ((next = cur->next) != NULL) {
if(next->data <= cur->data) {
swap(cur, next);
switchC++;
}
cur = next;
}
}
}
void main()
{
Node* first = initNode();
addNodes(10, first);
printNodes(first);
bubbleSort(first);
printNodes(first);
}
Output:
$ gcc main.c && ./a.out
100-99-98-97-96-95-94-93-92-91-90-89-
89-90-91-92-93-94-95-96-97-98-99-100-
You claim that the problem is in your Bubblesort implementation, but there is at least a problem in printNodes():
void printNodes(Node* first){
Node* cur = first;
int loopC = 0;
while(cur->next != NULL){
printf("%d-", cur->data);
loopC++;
cur = cur->next;
}
}
Observe that the last node in the list will not satisfy the condition cur->next != NULL, and therefore its value will not be printed. It is worth also mentioning at this point that the representations of the input and output linked lists presented in the OP were not produced by the version of printNodes() presented there, which begs the question of where they did come from.
It turns out that you are right about there being a bug in your sort, however. Both your swap() and your bubbleSort() are flawed. They accept the head pointer by value and return nothing, so when one of these functions tries to assign a different node to be the head node, that change does not propagate to the function's caller.
There are two possible solutions for that in the bubbleSort() function:
Pass a pointer to the head pointer:
void bubbleSort(Node **first) // ...
Erstwhile uses of first would need to be adjusted to *first.
Return the new value of first, making it the caller's responsibility to update its head-node pointer.
Node *bubbleSort(Node *first) {
// ...
return first;
}
The same applies to your swap() function, but there you have an additional option: restructure bubbleSort so that the prev argument to swap() is never null. You can do this by temporarily inserting a dummy head node in front of the true head, and structuring the sort passes so that the dummy is never evaluated for exchange with its successor. This permits you to make the head node an ordinary case instead of a special one. I leave the details to you to work out if you wish, but here's a start:
void bubbleSort(Node **first) {
Node dummy = { .next = *first };
// ...
*first = dummy.next;
}
If you pursue this then you should find that swap() does not need the third argument, as its prev will always be non-NULL (sometimes it may be &dummy). The simplification may even be enough that you decide you don't need a separate swap() function in the first place.

Circular linked list crashes when displayed

I'm trying to make a circular linked list. When I try to display the list after creating it, the program keeps on crashing. Here is my code:
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
int data;
struct node * next;
} node;
node * createList(int);
void display(node * head);
int main() {
struct node * head;
head = createList(5);
display(head);
}
node * createList(int n) {
int i = 0,data = 0;
struct node * head = NULL;
struct node * temp = NULL;
struct node * p = NULL;
for (i = 0; i < n; i++) {
temp = (node*)malloc(sizeof(node));
temp->data = data++;
temp->next = head;
if (head == NULL) {
head = temp;
} else {
p = head;
while (p->next != NULL) {
p = p->next;
}
p->next = temp;
}
}
return head;
}
void display(node * head) {
struct node * temp = head->next;
while (temp != head) {
printf("%d-> \t",temp->data);
temp = temp->next;
}
printf("\n");
}
What am I doing wrong?
You have set every temp's next to head in temp->next = head; but did it too early (the first is just NULL). Then you tested p->next against NULL in while (p->next != NULL) { but you should have tested against head. Alternatively, you can continue to test against NULL but then you need to initialize temp->next to NULL and assign head to temp->next only after the for loop.
Your display code started from the second link.
Here is a fixed code using the first option in 1. above:
for (i = 0; i < n; i++) {
temp = (node*)malloc(sizeof(node));
temp->data = data++;
if (head == NULL) {
head = temp;
} else {
p = head;
while (p->next != head) {
p = p->next;
}
p->next = temp;
}
temp->next = head;
}
Here is a fixed code using the alternative option in 1. above. You still need to initialize temp->next to NULL since malloc() does not initialize.
for (i = 0; i < n; i++) {
temp = (node*)malloc(sizeof(node));
temp->data = data++;
temp->next = NULL;
if (head == NULL) {
head = temp;
} else {
p = head;
while (p->next != NULL) {
p = p->next;
}
p->next = temp;
}
}
if (temp != NULL) {
temp->next = head;
}
But in reality, there is no need to "walk" from the head on every creation. You can simply keep the previous and link it to the next:
for (i = 0; i < n; i++) {
temp = (node*)malloc(sizeof(node));
temp->data = data++;
if (head == NULL) {
head = p = temp;
} else {
p = p->next = temp;
}
}
if (temp != NULL) {
temp->next = head;
}
Here is a fix for the display():
void display(node * head) {
struct node * temp = head;
if (temp != NULL) {
do {
printf("%d-> \t",temp->data);
temp = temp->next;
} while (temp != head);
}
printf("\n");
}
The problem is on the first node you initialize:
struct node *head = NULL;
...
for (i = 0; i < n; i++) {
...
temp->next = head;
So tmp->next == NULL on the first iteration leaving head->next == NULL. That will not work for a circular list. When you attempt to insert the 2nd node:
p = head;
while (p->next != NULL) {
What was head->next again?? (oh, NULL) Dereferencing a NULL pointer (BOOM Segfault!)
Do your circular list correctly. On insertion of the first node set:
if (head == NULL) {
head = temp;
head->next = temp; /* you must set head->next to temp */
} ...
So on the insertion of the remaining nodes you simply need:
} else {
p = head;
while (p->next != head) { /* iterate to last node */
p = p->next;
}
p->next = temp; /* now set p->next = temp */
}
Now, you handle your display() function the same way, e.g.
void display (node *head)
{
if (!head) { /* validate list not empty */
puts ("(list-empty)");
return;
}
struct node *temp = head;
do { /* same loop problem fixed in display() */
printf ("%d-> \t", temp->data);
temp = temp->next;
} while (temp != head);
putchar ('\n');
}
If you make the changes, then you can test your list with:
int main (void) {
struct node *head, *tmp;
head = createList(5);
display (head);
puts ("\niterate from mid-list");
tmp = head;
tmp = tmp->next;
tmp = tmp->next;
display (tmp);
}
Example Use/Output
$ ./bin/lls_circular_fix
0-> 1-> 2-> 3-> 4->
iterate from mid-list
2-> 3-> 4-> 0-> 1->
Lastly, you are not multiplying the type node by head in struct node * head = NULL; Write it as struct node *head = NULL; (the same for all your function declarations as well) Much more readable.
When you go to delete a note from the list, you must create a special case for both head and tail (the last node). In this sense, the singly-linked list takes a bit more effort than a doubly-linked list due to not having a prev node pointer to track the prior node.
Look things over and let me know if you have questions.
A full example would be:
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
int data;
struct node *next;
} node;
node *createList (int);
void display (node *head);
int main (void) {
struct node *head, *tmp;
head = createList(5);
display (head);
puts ("\niterate from mid-list");
tmp = head;
tmp = tmp->next;
tmp = tmp->next;
display (tmp);
}
node *createList (int n)
{
int i = 0,data = 0;
struct node *head = NULL;
struct node *temp = NULL;
struct node *p = NULL;
for (i = 0; i < n; i++) {
if (!(temp = malloc (sizeof *temp))) {
perror ("malloc-temp");
return NULL;
}
temp->data = data++;
temp->next = head; /* head is NULL on 1st node insertion */
if (head == NULL) {
head = temp;
head->next = temp; /* you must set head->next to temp */
} else {
p = head;
while (p->next != head) { /* iterate to last node */
p = p->next;
}
p->next = temp; /* now set p->next = temp */
}
}
return head;
}
void display (node *head)
{
if (!head) { /* validate list not empty */
puts ("(list-empty)");
return;
}
struct node *temp = head;
do { /* same loop problem fixed in display() */
printf ("%d-> \t", temp->data);
temp = temp->next;
} while (temp != head);
putchar ('\n');
}

c linked list delete smallest element [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
Lists seem really hard for me. I want to find the smallest element in a file: 1 5 8 6 4 8 6 48 9. It's 1 and I want to delete that 1. I can find the smallest element but can not delete it. I find the smallest element place but not the value. I tried copying deleting function from the web, however I cant understand it due to the fact that I'm really new to C. It writes an error that dereferencing to incomplete type. Please help. Post whole code because it should be more convenient to understand.
#include <stdio.h>
#include <stdlib.h>
typedef struct linkedList {
int value;
struct linkedList *next;
} linkedList, head;
linkedList *readList(linkedList *head) {
FILE *dataFile;
dataFile = fopen("duom.txt", "r");
if (dataFile == NULL) {
printf("Nepasisekė atidaryti failo\n");
} else {
printf("Duomenų failą pavyko atidaryti\n");
}
while (!feof (dataFile))
if (head == NULL) {
head = malloc(sizeof(linkedList));
fscanf(dataFile, "%d", &head->value);
head->next = NULL;
} else {
struct linkedList *current = head;
struct linkedList *temp = malloc(sizeof(linkedList));
while (current->next != NULL) {
current = current->next;
}
fscanf(dataFile, "%d", &temp->value);
current->next = temp;
temp->next = NULL;
}
return head;
}
void search(linkedList *head, int *lowest) {
int a[100];
int i = 0;
int minimum;
int b = 0;
linkedList *current = head;
while (current != NULL) {
a[i] = current->value;
current = current->next;
i++;
}
b = i;
i = 0;
minimum = a[0];
while (b > 0) {
if (minimum > a[i]) {
minimum = a[i];
lowest = i;
}
i++;
b--;
}
}
void deleteNode(struct node **head_ref, int key) {
struct node* temp = *head_ref, *prev;
if (temp != NULL && temp->data == key) {
*head_ref = temp->next; // Changed head
free(temp); // free old head
return;
}
while (temp != NULL && temp->data != key) {
prev = temp;
temp = temp->next;
}
if (temp == NULL)
return;
prev->next = temp->next;
free(temp);
}
void printList(linkedList *head) {
linkedList *current = head;
while (current != NULL) {
printf("%d->", current->value);
current = current->next;
}
printf("NULL\n");
return;
}
int main() {
linkedList *A = NULL;
A = readList(A);
search(A);
head = head->next;
minimum = head->value;
headk->next = head->next;
free(head);
printList(A);
return 0;
}
like this
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
typedef struct linkedList{
int value;
struct linkedList *next;
} linkedList, node;
linkedList *readList(void){
FILE *dataFile;
dataFile = fopen("duom.txt", "r");
if(dataFile == NULL) {
perror("file open");
return NULL;
}
int v;
node head = {0, NULL}, *curr = &head;
while (1 == fscanf(dataFile, "%d", &v)){
node *new_node = malloc(sizeof(node));
if(new_node == NULL){
perror("malloc");
break;
}
new_node->value = v;
new_node->next = NULL;
curr = curr->next = new_node;
}
fclose(dataFile);
return head.next;
}
int searchMin(linkedList *head){
if(head == NULL){
fprintf(stderr, "%s: The list MUST NOT be NULL.\n", __func__);
return INT_MIN;
}
int min = head->value;
node *p = head->next;
while(p){
if(p->value < min)
min = p->value;
p = p->next;
}
return min;
}
void deleteNode(node **head_ref, int key){
node *curr = *head_ref, *prev = NULL;
while (curr != NULL && curr->value != key){
prev = curr;
curr = curr->next;
}
if (curr == NULL) return;//not found
if(prev)
prev->next = curr->next;
else
*head_ref = curr->next;
free(curr);
}
void printList(linkedList *head){
node *current = head;
while (current != NULL) {
printf("%d->", current->value);
current = current -> next;
}
puts("NULL");
}
void freeList(linkedList *list){
while(list){
node *temp = list;
list = list->next;
free(temp);
}
}
int main(void){
linkedList *A = readList();
int min = searchMin(A);
printList(A);
deleteNode(&A, min);
printList(A);
freeList(A);
return 0;
}
Please try if this program can help you.
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
struct node {
int data;
struct node *next;
};
void push(struct node **head_ref, int new_data) {
struct node *new_node = (struct node *) malloc(sizeof(struct node));
new_node->data = new_data;
new_node->next = (*head_ref);
(*head_ref) = new_node;
}
void deleteNode(struct node **head_ref, int key) {
struct node *temp = *head_ref, *prev;
if (temp != NULL && temp->data == key) {
*head_ref = temp->next;
free(temp);
return;
}
while (temp != NULL && temp->data != key) {
prev = temp;
temp = temp->next;
}
if (temp == NULL) return;
prev->next = temp->next;
free(temp);
}
void printList(struct node *node) {
while (node != NULL) {
printf(" %d ", node->data);
node = node->next;
}
}
void min(struct node **q) {
struct node *r;
int min = INT_MAX;;
r = *q;
while (r != NULL) {
if (r->data < min) {
min = r->data;
}
r = r->next;
}
printf("The min is %d", min);
deleteNode(q, min);
printf("\n");
}
int main() {
struct node *head = NULL;
FILE *file = fopen("duom.txt", "r");
int i = 0;
fscanf(file, "%d", &i);
while (!feof(file)) {
push(&head, i);
fscanf(file, "%d", &i);
}
fclose(file);
puts("Created Linked List: ");
printList(head);
min(&head);
puts("\nLinked List after Deletion of minimum: ");
printList(head);
return 0;
}
file duom.txt
1 5 8 6 4 8 6 48 9
Test
./a.out
Created Linked List:
9 48 6 8 4 6 8 5 1 The min is 1
Linked List after Deletion of minimum:
9 48 6 8 4 6 8 5 ⏎

appending node to link list (I am almost there) in C

I am trying to figure out how to append a node to the link list.
I feel like I am almost there but after staring at the code for a while now I cant think of whats wrong with it.
I have to mention that after adding first int to the list I get segmentation fault...
typedef struct node
{
int data;
struct node* next;
}
node;
node* head;
void append(node* pHead, int data)
{
node* current = pHead;
node* newNode = NULL;
newNode = (node*)malloc(sizeof(node));
newNode->data = data;
newNode->next = NULL;
if (current == NULL)
pHead = newNode;
else
{
while (current->next != NULL)
current = current->next;
}
current->next = newNode;
}
int main(void)
{
head = NULL;
int howMany;
int num;
printf("how many?");
scanf("%d", &howMany);
for (int i = 0; i < howMany; i++)
{
printf("** %d ** number: ", i+1);
scanf("%d", &num);
append(head, num);
}
Where is my error?
I think the problem is here:
if (current == NULL)
pHead = newNode;
else
{
while (current->next != NULL)
current = current->next;
}
current->next = newNode;
That last line, current->next = newNode, should be inside the else body, otherwise you will try to dereference a NULL pointer when current is NULL.
So, it should be:
if (current == NULL)
pHead = newNode;
else
{
while (current->next != NULL)
current = current->next;
current->next = newNode;
}
Another problem is that you never modify head. You only modify the private, local copy of the head pointer inside append(). This modification is not visible outside of append(), so the program ends up leaking memory and you can never access the list (because head is always NULL). You can either make pHead a node ** (so that modifications to *pHead are visible), or instead you can modify head inside append(), instead of passing it as an argument. This will work because you won't be modifying a private local copy. Here's how append() should look like:
void append(int data)
{
node* current = head;
node* newNode = NULL;
newNode = (node*)malloc(sizeof(node));
newNode->data = data;
newNode->next = NULL;
if (current == NULL)
head = newNode;
else
{
while (current->next != NULL)
current = current->next;
current->next = newNode;
}
}
You do current->next = newNode; even if current is NULL.
You must return from function when (current == NULL):
if (current == NULL) {
pHead = newNode;
return;
}
else
{
while (current->next != NULL)
current = current->next;
}
current->next = newNode;
or put current->next = newNode; in else statement:
if (current == NULL) {
pHead = newNode;
}
else
{
while (current->next != NULL)
current = current->next;
current->next = newNode;
}
Full example:
#include <stdio.h>
#include <stdlib.h>
typedef struct node
{
int data;
struct node* next;
}
node;
node* head;
void append(node* pHead, int data)
{
node* current = pHead;
node* newNode = NULL;
newNode = (node*)malloc(sizeof(node));
newNode->data = data;
newNode->next = NULL;
if (current == NULL) {
pHead = newNode;
return;
}
else
{
while (current->next != NULL)
current = current->next;
}
current->next = newNode;
}
int main(void)
{
head = NULL;
int howMany;
int num;
printf("how many?");
scanf("%d", &howMany);
for (int i = 0; i < howMany; i++)
{
printf("** %d ** number: ", i + 1);
scanf("%d", &num);
append(head, num);
}
}

Resources