Search code examples
cdoubly-linked-listinsertion-sort

C Doubly Linked List w/ Insertion Sort keeps overwriting if Inputted Data is not at the End of the List


Im trying to implement an Insertion Sort Doubly Linked List with User Input that sorts the List every time the User inputs data.

My code works just fine if you call the insertion sort function after all the data have been inputted by the user.

User Input: 5  
User Input: 1
User Input: 3
User Input: 8
User Input: 7
User Input: 9

Unsorted List: 5  1  3  8  7  9

//Insertion Sort Function gets called after all the data have been entered//

Output: 1  3  5  7  8  9

But it gets messed up if I call the insertion sort function every time the user inputs a new data and somehow, it overwrites the next node if the inserted node is not at the end of list even though it has successfully inserted the new data in between the list.

User Input: 1
//Insertion Sort Function gets called//
Output: 1

User Input: 2
//Insertion Sort Function gets called//
Output: 1  2

User Input: 9
//Insertion Sort Function gets called//
Output: 1  2  9

User Input: 3
//Insertion Sort Function gets called//
Output: 1  2  3 9

User Input: 4
//Insertion Sort Function gets called//
Output: 1  2  3  4

As you can see, the 3 gets inserted just fine into the List but somehow, my code thinks that the end of the list is now after 3 so when I input a new data, for example, 4 into the new list, 9 gets overwritten because it thinks that 3 was the end of the list.

Is there something wrong with my insertion sort function?

How do I navigate back to the end of the list and make it so it adds the new data at the end of the list?

my whole code is included below,

#include<stdio.h> 
#include<stdlib.h> 
  
//// structure for a node ////
struct Node 
{ 
    int data; 
    struct Node *prev;
    struct Node *next; 
}; 


typedef struct Node NODE;
  
void UserInput();
void printList(struct Node *head, );
void insertionSort(struct Node **head_ref);
void sortedInsert(struct Node** head_ref, struct Node* newNode);

  
void main() 
{ 
UserInput();

_getch();  
} 




void UserInput()
{
    
    int loop=0; 
    int data;
  
    struct Node *temp;
    NODE *tail = NULL;
    
    
    struct Node *head;
    head = (struct Node*)malloc(sizeof(struct Node));  ////create node, store address to temp
    
        printf("\nEnter Data: "); 
        scanf(" %d" , &data);
        head->data = data;
        head->prev = NULL; //// head node's prev is set to NULL
        head->next = NULL; //// head node's next is set to NULL
        tail = head;
        printList(head);
      
    while (loop < 9999) 
    {
        temp = (struct Node*)malloc(sizeof(struct Node));  ////create node, store address to temp
        printf("\nEnter Data: "); 
        scanf(" %d" , &data);
        if(data == 9999)
        {
            break;
        }
        
        temp->data = data;
        printList(head);
        temp->prev = tail; //// prev pointer of temp is referenced to the last node
        temp->next = NULL; //// next pointer of temp is NULL
        tail->next = temp; //// next pointer of the tail node is referenced to the temp
        tail = temp;       //// temp is made as the tail node
        
        insertionSort(&head);
        printList(head);
        loop++;
    }
    
    
    printf("Insertion of Numbers Terminated.");
    //// If insertionSort function is called after all  User Inputs, there are no problems in sorting.
    //insertionSort(&temp);
    printList(temp);

    
}

////Printing Function to get called every loop////
void printList(struct Node *head) 
{ 
 struct Node *temp1 = head; 

 temp1 = head;
 
 printf("\nSorted Numbers: ");

 while(temp1 != NULL)
 {
 printf(" %d ", temp1->data);
 temp1 = temp1->next;
 }
 
}
  

////Insertion Sort Algorithm to sort the list////
void insertionSort(struct Node **head_ref) 
{ 
    //// Initialize 'sorted' - a sorted doubly linked list 
    struct Node* sorted = NULL; 
  
    //// Traverse the given doubly linked list and insert every node to 'sorted' 
    struct Node* current = *head_ref; 
    while (current != NULL) { 
  
        //// Store next for next iteration 
        struct Node* next = current->next; 
  
        //// removing all the links so as to create 'current' as a new node for insertion 
        current->prev = current->next = NULL; 
  
        //// insert current in 'sorted' doubly linked list 
        sortedInsert(&sorted, current); 
  
        //// Update current 
        current = next; 
    } 
  
    //// Update head_ref to point to sorted doubly linked list 
    *head_ref = sorted;
} 



void sortedInsert(struct Node** head_ref, struct Node* newNode) 
{ 
    struct Node* current; 
  
    //// if list is empty 
    if (*head_ref == NULL)
    {
        *head_ref = newNode;
    }
    //// if the node is to be inserted at the beginning of the doubly linked list 
    else if ((*head_ref)->data >= newNode->data) 
    { 
        newNode->next = *head_ref; 
        newNode->next->prev = newNode; 
        *head_ref = newNode; 
    }
  
    else 
    { 

        current = *head_ref; 
  
        //// locate the node after which the new node is to be inserted 
        while (current->next != NULL && current->next->data < newNode->data)
        {
            current = current->next;
        }
  
        ////Make the appropriate links ////
  
        newNode->next = current->next; 
  
        //// if the new node is not inserted at the end of the list 
        if (current->next != NULL)
        {
            newNode->next->prev = newNode;
        }

        current->next = newNode; 
        newNode->prev = current; 
    } 
}

Solution

  • The problem is in UserInput() while inserting the data the temp node's next should point to the tail's next so change this line

    temp->next = NULL; 
    

    into this

    temp->next = tail->next; 
    

    Why?? Because you are swapping the nodes themselves so after each insertionSort() the next of updated tail is not going to be NULL but its pointing to some previously added node's address since we are swapping the nodes so the addresses are being interchanged. Check the sample code here: https://ideone.com/gSKK7B