I'm busy with implementation of singly linked list and have 2 functions: insert_back and insert_after.
Here is the listing of them:
void insert_back(int data)
{
node *temp1;
temp1 = (node*)malloc(sizeof(node));
temp1 = head;
while (temp1->next != NULL) {
temp1 = temp1->next;
}
node *temp;
temp = (node*)malloc(sizeof(node));
temp->data = data;
temp->next = NULL;
temp1->next = temp;
}
void insert_after(int pos, int data)
{
node *temp1;
temp1 = (node*)malloc(sizeof(node));
temp1 = head;
for (int i = 1; i < pos; i++) {
temp1 = temp1->next;
if (temp1 == NULL) {
return;
}
}
node *temp;
temp = (node*)malloc(sizeof(node));
temp->data = data;
temp->next = temp1->next;
temp1->next = temp;
}
As you can see they are almost the same and for insert back I want to write insert_after(null, 10). I can solve it by adding if condition and choose one of the loops, but it's not my aim.
Is it possible somehow to use one while or for loops together for serial numbers and null?
Also I see that param int pos is int. Should I use 0 instead of null?
You unnecessarily allocate memory in the following lines.
temp1 = (node*)malloc(sizeof(node));
temp1 = head;
This allocated memory will leak as you overwrite the returned address in temp1. You just need temp1 to walk over the list, so there is also no need to allocate any node itself. temp1 can point to any node.
I've taken the liberty to kind of from scratch write a routine doing both things in one go. If pos < 0 it will add the element to the end of the list, otherwise it will add it after the pos-th element, where the first element corresponds with pos == 1. If pos == 0 the element is added at the start of the list.
Also a small main is added to test the routine. new_node has been added to test if memory is not exhausted.
#include <stdlib.h>
#include <stdio.h>
typedef struct node
{
struct node * next;
int data;
} node;
node * head = NULL;
node * new_node(void)
{
node * result = malloc(sizeof(*result));
if (result == NULL)
{
fprintf(stderr, "Out of memory.\n");
exit(10);
}
return result;
}
void insert_after(int pos, int data)
{
node *walk, * prev;
int i;
prev = NULL;
walk = head;
for (i = 0; walk != NULL && i != pos; i++)
{
prev = walk;
walk = walk->next;
}
if (i != pos && pos > 0)
{
fprintf(stderr, "Location not found.\n");
exit(9);
}
else
{
walk = new_node();
walk->data = data;
if (prev == NULL)
{
walk->next = head;
head = walk;
}
else
{
walk->next = prev->next;
prev->next = walk;
}
}
}
int main(void)
{
int i;
node * wlk;
for (i = 0; i < 10; i++)
{
insert_after(-1, i);
}
for (i = 0; i < 10; i++)
{
insert_after(3, i+10);
}
for (wlk = head; wlk != NULL; wlk = wlk->next)
{
printf("%d\n", wlk->data);
}
return 0;
}
Since you are testing for the end of the chain with insert_after(pos,...) anyway, you could go for:
void insert_after(int pos, int data)
{
node *temp1= head;
for (int i=1; i<pos; i++) {
if (temp1->next==NULL) {
if (pos==INT_MAX)
break; // pos of INT_MAX means insert at end
// so we continue with this last item and append
else
return; // pos higher than length of chain
}
temp1 = temp1->next;
}
...
}
Or slightly more compact:
void insert_after(int pos, int data)
{
node *temp1= head;
for (int i=1; i<pos && temp1->next!=NULL; i++) {
temp1 = temp1->next;
}
if (temp1->next==NULL && pos!=INT_MAX)
return; // pos higher than length of chain, except for
// INT_MAX (for that we just want to continue)
...
}
Then you could use
void insert_back(int data)
{
insert_after(INT_MAX, data);
}
Related
I'm trying to implement radix sort on a linked list based on an integer with the code below.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_DIGITS 10 // maximum number of digits in a key
// Structure for a node in the linked list
typedef struct node
{
int key; // the key to be sorted
char value[20]; // the value associated with the key
struct node *next; // pointer to the next node in the list
} Node;
// Function prototypes
void radixSort(Node **head);
Node *createNode(int key, const char *value);
Node *append(Node *head, int key, const char *value);
void printList(Node *head);
int main(void)
{
Node *head = NULL; // head of the linked list
// Create a linked list with some random keys and values
head = append(head, 456, "apple");
head = append(head, 345, "banana");
head = append(head, 123, "cherry");
head = append(head, 789, "date");
head = append(head, 231, "elderberry");
head = append(head, 567, "fig");
head = append(head, 876, "grape");
// Print the original list
printf("Original list:\n");
printList(head);
// Sort the list using radix sort
radixSort(&head);
// Print the sorted list
printf("Sorted list:\n");
printList(head);
return 0;
}
// Function to sort the linked list using radix sort
void radixSort(Node **head)
{
Node *bucket[10]; // array of buckets
Node *curr; // pointer to the current node
Node *tail[10]; // array of tails for each bucket
int i, j, k;
int factor; // factor to sort on
int digits[MAX_DIGITS]; // array to store the digits of the keys
// Initialize the buckets and tails
for (i = 0; i < 10; i++)
{
bucket[i] = NULL;
tail[i] = NULL;
}
// Find the maximum number of digits in the keys
int maxDigits = 0;
curr = *head;
while (curr != NULL)
{
int key = curr->key;
int numDigits = 0;
while (key > 0)
{
numDigits++;
key /= 10;
}
if (numDigits > maxDigits)
{
maxDigits = numDigits;
}
curr = curr->next;
}
// Loop through each digit, starting with the least significant digit
for (factor = 1; maxDigits > 0; factor *= 10, maxDigits--)
{
// Extract the digits of the keys
curr = *head;
while (curr != NULL)
{
digits[curr->key / factor % 10]++;
curr = curr->next;
}
// Cumulative sum of the digits
for (i = 1; i < 10; i++)
{
digits[i] += digits[i - 1];
}
// Sort the nodes into the appropriate buckets
curr = *head;
while (curr != NULL)
{
int digit = curr->key / factor % 10;
if (bucket[digit] == NULL)
{
bucket[digit] = curr;
tail[digit] = curr;
}
else
{
tail[digit]->next = curr;
tail[digit] = curr;
}
curr = curr->next;
}
// Rebuild the list in sorted order
*head = NULL;
for (i = 9; i >= 0; i--)
{
//printf("%dA\n",i);
if (bucket[i] != NULL)
{
//printf("%dB\n",i);
if (*head == NULL)
{
*head = bucket[i];
// printf("%dC\n",i);
}
else
{
//printf("%dD\n",i);
tail[9 - i]->next = bucket[i];
//printf("%dF\n",i);
}
// tail[9 - i] = tail[i];
}
else{
// printf("%dE\n",i);
}
//printf("here\n");
}
}
}
// Function to create a new node with the given key and value
Node *createNode(int key, const char *value)
{
Node *node = (Node*) malloc(sizeof(Node));
node->key = key;
strcpy(node->value, value);
node->next = NULL;
return node;
}
// Function to append a new node with the given key and value to the end of the list
Node *append(Node *head, int key, const char *value)
{
Node *newNode = createNode(key, value);
Node *curr = head;
if (head == NULL)
{
return newNode;
}
while (curr->next != NULL)
{
curr = curr->next;
}
curr->next = newNode;
return head;
}
// Function to print the linked list
void printList(Node *head)
{
Node *curr = head;
while (curr != NULL)
{
printf("(%d, %s) ", curr->key, curr->value);
curr = curr->next;
}
printf("\n");
}
The segmentation fault occurs when tail[9 - i]->next = bucket[i]; is executed.
I added printf statements (turned them into comment blocks) to trace where the error is. Can someone please help me figure out a way to get this to work?
There are a few issues:
tail[9 - i]->next = bucket[i]; sets the wrong pointer. There is no reason why it should be 9 - i. It could even be that tail[9 - i] is NULL. So this leads to indefined behaviour. Instead you should keep track of what the current tail node is in the list that is being built. You could use curr for that purpose. Let it start (before the loop) with curr = NULL and then when you find a non-null bucket, end that process by setting curr = tail[i]. When a bucket is found when the *head is no longer NULL, make the link with curr->next = bucket[i].
The new list is not terminated with a NULL pointer. When the above point is implemented, continue after the loop with curr->next = NULL.
In the next iteration of the factor loop, both digits and buckets need to be reset. You could do this with a loop or with memset.
Here is the corrected factor loop code -- comments indicate where corrections were made:
for (factor = 1; maxDigits > 0; factor *= 10, maxDigits--)
{
memset(digits, 0, sizeof(digits)); // reset!
memset(bucket, 0, sizeof(bucket)); // reset!
curr = *head;
while (curr != NULL)
{
digits[curr->key / factor % 10]++;
curr = curr->next;
}
for (i = 1; i < 10; i++)
{
digits[i] += digits[i - 1];
}
curr = *head;
while (curr != NULL)
{
int digit = curr->key / factor % 10;
if (bucket[digit] == NULL)
{
bucket[digit] = curr;
tail[digit] = curr;
}
else
{
tail[digit]->next = curr;
tail[digit] = curr;
}
curr = curr->next;
}
*head = NULL;
curr = NULL; // <-- track the current tail of the newly built list
for (i = 9; i >= 0; i--)
{
if (bucket[i] != NULL)
{
if (*head == NULL)
{
*head = bucket[i];
}
else
{
curr->next = bucket[i]; // Append bucket after the current tail
}
curr = tail[i]; // The tail is now at the end of this bucket
}
}
curr->next = NULL; // Terminate the list properly
}
i have a simple linked list that looks like this
typedef struct Node {
void *data;
struct Node *next
} Node;
typedef struct Node {
Node *head;
Node *tail;
int size;
} LinkedList
And my add_node function looks like this :
void add_nth_node(LinkedList *list, int n, void *new_data) {
Node *prev, *curr;
Node *new_node;
if (list == NULL) {
return;
}
/* n >= list->size inseamna adaugarea unui nou nod la finalul listei. */
if (n > list->size) {
n = list->size;
} else if (n < 0) {
return;
}
curr = list->head;
prev = NULL;
while (n > 0) {
prev = curr;
curr = curr->next;
--n;
}
new_node = malloc(sizeof(Node));
if (new_node == NULL) {
perror("Not enough memory to add element!");
exit(-1);
}
new_node->data = new_data;
new_node->next = curr;
if (prev == NULL) {
/* Adica n == 0. */
list->head = new_node;
} else {
prev->next = new_node;
}
if (new_node->next == NULL) {
list->tail = new_node;
}
list->size++;
There is something weird when i try to add nodes to the list.
When i add them like this :
int i;
for (i = 0; i < 10; i++) {
add_nth_node(list, i, &i);
}
But when i add elements like this :
int i, v[10];
for(i = 0; i < 10; i++) {
v[i] = i;
add_nth_node(list_1, i, &v[i]);
}
Everything is working as expected. Why is that ?
Why do i have to put elements is a vector first to add them to the list.
add_nth_node(list, i, &i) // (1)
// and
add_nth_node(list_1, i, &v[i]); // (2)
They are not the same but the value of data that you assign for each node is the same in two options.
(1) You make the pointer point to address of i.
(2) You make the pointer point to address of v[i].
Use (1) is very bad idea because, in this case all data of all nodes point to the same address. So if the data of one node changes, the data of all nodes change the value.
I'm trying to create a sorted list in ascending order. I must read a file which contains a year in every line ( so I want to order from the earliest date to the most recent).
What I'm trying to accomplish with my code is:
List item
Retrieve data (year) from a line of the .csv file;
Iterate over the list until the place for the node containing data is found;
Repeat until the file is over;
Print;
Whenever I try to run it, the Virtual box starts lagging and doesn't do anything. (even when I remove the print function).
I've been trying to solve this for 3 days now, so I'm quite desperate.
Here's my code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
struct node {
int data;
int key;
struct node *next;
} node;
struct node *head_countries = NULL;
struct node *current = NULL;
//display the list
void printList() {
struct node *ptr = head_countries;
printf("\n[ ");
//start from the beginning
while(ptr != NULL) {
printf("(%d,%d)",ptr->key,ptr->data);
ptr = ptr->next;
}
printf(" ]");
}
//insert link at the first location
struct node* insertFirst(int key, int data) {
//create a link
struct node *link = (struct node*) malloc(sizeof(struct node));
link->key = key;
link->data = data;
//point it to old first node
link->next = head_countries;
//point first to new first node
head_countries = link;
return link;
}
void insertAfter(struct node* PrevNode, int key, int data)
{
struct node *NewNode = (struct node*) malloc(sizeof(struct node));
if ( PrevNode == NULL )
{
printf("Erro 1");
return;
}
NewNode->key = key;
NewNode->data = data;
NewNode->next = PrevNode->next;
PrevNode->next = NewNode;
}
void CreateCountriesList()
{
char linha[150];
char cabecalho[100];
int key = 0, data = 0;
int test[15] = {0};
test[0] = 10;
test[1] = 25;
test[2] = 7;
test[3] = 5;
test[4] = 30;
test[5] = 40;
test[6] = 3;
test[7] = 4;
test[8] = 98;
test[10] = 4;
test[11] = 14;
test[12] = 23;
test[13] = 16;
test[14] = 35;
test[15] = 6;
//dados_temp New_Entry;
struct node* curr_head = NULL;
struct node* curr = NULL;
FILE *inputf;
inputf = fopen("tempcountries_all.csv", "r");
if (inputf == NULL)
{
printf("Nao da pa abrir o ficheiro");
exit(EXIT_FAILURE);
}
fgets(cabecalho, 100, inputf);
for (key = 0; key < 20 ; key++)
{
data = test[key]
if ( head_countries == NULL || key == 2 )
{
insertFirst( key, data );
}
else
{
curr = head_countries;
//insertAfter(curr, key, data);
//printf("%d\n", curr->data);
//curr = curr->next;
while ( curr->next != NULL )
{
//printf("%d", key);
if ( curr->data < data && curr->next->data > data )
{
insertAfter(curr, key, data);
}
if ( data == curr->data )
{
//insertAfter(curr, key, data);
}
curr = curr->next;
}
}
}
printList();
fclose(inputf);
}
int main() {
CreateCountriesList();
return EXIT_SUCCESS;
}
Is it because the list is too big? If so, how do you recommend I proceed for a list this big?
Thank you in advance!
EDIT: removed warnings from code, and unused functions.
EDIT: added test.
You have several problems, but the most significant one seems to revolve around how you insert data into the list:
while ( curr->next != NULL )
{
//printf("%d", key);
if ( curr->data < data && curr->next->data > data )
{
insertAfter(curr, key, data);
}
if ( data == curr->data )
{
//insertAfter(curr, key, data);
}
curr = curr->next;
}
You do not break from the loop after performing an insertion, so observe what happens:
You find an appropriate predecessor, P, for the data you want to insert. curr will at that time point to P.
You insert the a new node, N, after P.
You continue iterating through the list. The next node you consider is the successor to P, which is now N.
N also meets the conditions for predecessor to your data (data == N.data), so you insert another new node. And another. And another ...
This will continue indefinitely, and the computer is indeed likely to start slowing down before too long, as its physical and virtual memory become loaded down with all the nodes the program allocates.
So i guess your biggest problem is to make that list...
This is how i would make those functions.
#include<stdio.h>
#include<stdlib.h>
typedef struct node {
int data;
int key;
struct node *next;
} node;
node *new_node(int key, int data)
{
node * n =malloc(sizeof(node));
if(!n)
{
fprintf(stderr,"malloc failed");
exit(EXIT_FAILURE);
}
n->data = data;
n->key = key;
n->next = NULL;
}
node *insert_middle(node *next, int key, int data)
{
node *new = new_node(key,data);
new->next = next;
return new;
}
node * insert_node(node *n, int key, int data)
{
if(!n)
{
return new_node(key, data);
}
else if(n->data < data)
{
n->next = insert_node(n->next, key, data);
}
else
{
return insert_middle(n, key, data);
}
}
int main()
{
node *head=NULL;
node *tmp = NULL;
int i,j;
for(i=0;i<10;i++)
{
scanf("%d",&j);
tmp = insert_node(head, 0, j);
//keep track of the head
if(tmp!=head)
head = tmp;
}
printf("====================");
while(head)
{
printf("%d\n",head->data);
head=head->next;
}
return 0;
}
Some bugs in your code i have found:
for (key = 0; key < 20 ; key++)
{
//you never change the value of data
data = test[0];
if ( head_countries == NULL || key == 2 )
{
//you should place curr = insertFirst(key, data);
//the way you have written the code nothing happens
//inserFirst function just return the vale and you don't store it anywhere so you can not use it
insertFirst( key, data );
}
else
{
curr = head_countries;
//after this line of code curr=NULL in first iteration
//curr->next will cause SIGSEGV since curr=NULL, so NULL->next is not possible
while ( curr->next != NULL )
{
//printf("%d", key);
if ( curr->data < data && curr->next->data > data )
{
insertAfter(curr, key, data);
}
if ( data == curr->data )
{
//insertAfter(curr, key, data);
}
curr = curr->next;
}
Too many bugs... I think you should start again.
If you dont understand my example just comment and i will give my best to explain
I was tasked with implementing a merge sort algorithm on a list written in C/C++. I have the general idea down, wrote my code and have successfully compiled it. However, when I run it, it will begin fine but then hang on "prepared list, now starting sort" without giving any kind of error. I have tried to look through my code but I am at a complete loss as to what the issue could be. I am also pretty amateurish with debugging, so using gdb to the best of my abilities has lead me no where. Any advice or tips would be a tremendous help, thank you all!
#include <stdio.h>
#include <stdlib.h>
struct listnode
{
struct listnode *next;
int key;
};
//Finds length of listnode
int
findLength (struct listnode *a)
{
struct listnode *temp = a;
int i = 0;
while (temp != NULL)
{
i++;
temp = temp->next;
}
return i;
}
struct listnode *
sort (struct listnode *a)
{
// Scenario when listnode is NULL
if (findLength (a) <= 1)
return a;
//Find middle
int mid = findLength (a) / 2;
struct listnode *temp = a;
struct listnode *first = a;
struct listnode *second;
for (int i = 0; i < mid - 1; i++)
{
temp = a->next;
}
second = temp->next;
temp->next = NULL;
//Recursive calls to sort lists
first = sort (first);
second = sort (second);
if (first != NULL && second != NULL)
{
if (first->key < second->key)
{
a = first;
first = first->next;
}
else
{
a = second;
second = second->next;
}
}
struct listnode *head = a;
struct listnode *tail = a;
while (first != NULL && second != NULL)
{
if (first->key < second->key)
{
tail = first;
first = first->next;
tail = tail->next;
}
else
{
tail = second;
second = second->next;
tail = tail->next;
}
}
if (first == NULL)
{
while (second != NULL)
{
tail = second;
second = second->next;
tail = tail->next;
}
}
while (first != NULL)
{
tail = first;
first = first->next;
tail = tail->next;
}
return a;
}
Here is the test code provided, written in C:int
main (void)
{
long i;
struct listnode *node, *tmpnode, *space;
space = (struct listnode *) malloc (500000 * sizeof (struct listnode));
for (i = 0; i < 500000; i++)
{
(space + i)->key = 2 * ((17 * i) % 500000);
(space + i)->next = space + (i + 1);
}
(space + 499999)->next = NULL;
node = space;
printf ("\n prepared list, now starting sort\n");
node = sort (node);
printf ("\n checking sorted list\n");
for (i = 0; i < 500000; i++)
{
if (node == NULL)
{
printf ("List ended early\n");
exit (0);
}
if (node->key != 2 * i)
{
printf ("Node contains wrong value\n");
exit (0);
}
node = node->next;
}
printf ("Sort successful\n");
exit (0);
}
You're close, but with some silly errors. Check the append operations in the merge step. They're not doing what you think they are. And of course you meant temp = temp->next; in the splitting loop.
If gdb is overwhelming, adding printf's is a perfectly fine way to go about debugging code like this. Actually you want to write a list printing function and print the sublists at each level of recursion plus the results of the merge step. It's fun to watch. Just be neat and delete all that when you're done.
Here's code that works for reference:
struct listnode *sort(struct listnode *lst) {
if (!lst || !lst->next) return lst;
struct listnode *q = lst, *p = lst->next->next;
while (p && p->next) {
q = q->next;
p = p->next->next;
}
struct listnode *mid = q->next;
q->next = NULL;
struct listnode *fst = sort(lst), *snd = sort(mid);
struct listnode rtn[1], *tail = rtn;
while (fst && snd) {
if (fst->key < snd->key) {
tail->next = fst;
tail = fst;
fst = fst->next;
} else {
tail->next = snd;
tail = snd;
snd = snd->next;
}
}
while (fst) {
tail->next = fst;
tail = fst;
fst = fst->next;
}
while (snd) {
tail->next = snd;
tail = snd;
snd = snd->next;
}
tail->next = NULL;
return rtn->next;
}
On my old MacBook this sorts 10 million random integers in a bit over 4 seconds, which doesn't seem too bad.
You can also put the append operation in a macro and make this quite concise:
struct listnode *sort(struct listnode *lst) {
if (!lst || !lst->next) return lst;
struct listnode *q = lst, *p = lst->next->next;
while (p && p->next) {
q = q->next;
p = p->next->next;
}
struct listnode *mid = q->next;
q->next = NULL;
struct listnode *fst = sort(lst), *snd = sort(mid);
struct listnode rtn[1], *tail = rtn;
#define APPEND(X) do { tail->next = X; tail = X; X = X->next; } while (0)
while (fst && snd) if (fst->key < snd->key) APPEND(fst); else APPEND(snd);
while (fst) APPEND(fst);
while (snd) APPEND(snd);
tail->next = NULL;
return rtn->next;
}
Does it have to be a top down merge sort? To get you started, here's a partial fix, didn't check for other stuff. The | if (first != NULL && second != NULL) | check isn't needed since the prior check for length <= 1 takes care of this, but it won't cause a problem.
while (first != NULL && second != NULL)
{
if (first->key < second->key)
{
tail->next = first;
tail = first;
first = first->next;
}
else
{
tail->next = second;
tail = second;
second = second->next;
}
}
if (first == NULL)
{
tail->next = second;
}
else
{
tail->next = first;
}
}
I have written a piece of code that uses linked lists. I get the user to enter a couple of numbers and then ask the user to enter the index of the digit he wishes to delete. I did some research and found out that i need to check whether the next node is the one I want to delete, then have 2 temp pointers point to the current node and the next node(which is the one i want to delete), then assign the next node of the first temp pointer to the next node of the second temp pointer then finally free the second temp pointer. Here is my code:
#include <stdio.h>
#include <stdlib.h>
typedef struct node
{
int item;
struct node *next;
}ListNode;
void print(ListNode *head);
int deleteNode(ListNode **ptrHead, int index);
int main()
{
int n;
int remove;
ListNode *head = NULL;
ListNode *temp = NULL;
printf("Enter a value: ");
scanf("%d", &n);
while (n != -1)
{
if (head == NULL)
{
head = malloc(sizeof(ListNode));
temp = head;
}
else
{
temp->next = malloc(sizeof(ListNode));
temp = temp->next;
}
temp->item = n;
temp->next = NULL;
printf("Enter a value: ");
scanf("%d", &n);
}
printf("Enter index to remove: ");
scanf("%i", &remove);
while (remove != -1)
{
deleteNode(&head, remove);
print(head);
printf("Enter index to remove: ");
scanf("%i", &remove);
}
while (head != NULL)
{
temp = head;
head = head->next;
free(temp);
}
head = NULL;
return 0;
}
int deleteNode(ListNode **ptrHead, int index)
{
int count = 0;
ListNode* temp1 = NULL;
ListNode* temp2 = NULL;
while (count <= index)
{
if (index == 0)
{
temp2 = (*ptrHead)->next;
free((*ptrHead));
(*ptrHead) = temp2;
return 0;
break;
}
if (count+1 == index)//checking for the node ahead
{
temp1 = (*ptrHead);
temp2 = (*ptrHead)->next;//the one to free
temp1->next = temp2->next;
free(temp2);
return 0;
break;
}
(*ptrHead) = (*ptrHead)->next;
count++;
}
return -1;
}
void print(ListNode *head){
if (head == NULL)
{
return;
}
while (head != NULL)
{
printf("%i\n", head->item);
head = head->next;
}
}
So for example if i enter 1 2 3 4 5 -1, the linked list will contain 1 2 3 4 5. Then if i enter 0 for the index to remove, the program will print out 2 3 4 5. This works whether I enter 0 or 1. However, when I enter the indexes 2 and above, it gives me weird outputs like for example if I set the linked list as 1 2 3 4 5, and enter the index 2 to remove, by rights it should output 1 2 4 5, but instead it outputs 2 4 5, I have no idea whats going on, please point me in the right direction.
In deleteNode you use the actual headpointer to traverse the list. As you loop through the list you move the actual head! You should only modify (*ptrHead) when you delete the first element.
I suggest that you copy *ptrHead to a local variable and use the local variable to traverse the list.
I've highlighted the important lines with comments starting with // ***
int deleteNode(ListNode **ptrHead, int index)
{
int count = 0;
ListNode* temp1 = NULL;
ListNode* temp2 = NULL;
ListNode* traverse = *ptrHead; // *** make a copy that we can use to traverse the list
while (count <= index)
{
if (index == 0)
{
temp2 = (*ptrHead)->next;
free((*ptrHead));
(*ptrHead) = temp2; // *** Keep this line as it is to correctly handle deletion of index 0.
return 0;
break;
}
if (count+1 == index)//checking for the node ahead
{
temp1 = traverse; // *** Use local copy of pointer
temp2 = traverse->next;//the one to free // *** Use local copy of pointer
temp1->next = temp2->next;
free(temp2);
return 0;
break;
}
traverse = traverse->next; // *** Use local copy of pointer
count++;
}
return -1;
}
Find the modified deleteNode function (handles boundary conditions also , if we are trying to delete an index which is more then the list length)
int deleteNode(ListNode **ptrHead, int index)
{
int count = 0;
ListNode* temp1 = NULL;
ListNode* temp2 = NULL;
temp1 = (*ptrHead);
while((temp1 != NULL) && (count <= index))
{
if (index == 0)
{
temp2 = temp1->next;
free(temp1);
(*ptrHead) = temp2;
return 0;
}
if ((count+1 == index) && (temp1->next != NULL))
{
ListNode*temp = NULL;
temp = temp1->next;
temp2 = temp->next;
temp1->next = temp2;
free(temp);
return 0;
}
temp1 = temp1->next;
count++;
}
return -1;
}