Ty Malik 🐦‍🔥

Programming parsers, compilers,
desktop and web apps

Insertion Sort List

Dynamic Programming: LeetCode

Published:

Updated:

Summary

Iterative and Intuitive

Iterate the original list with a temporary sorted list and a variable tracking the node from the original list. Find the correct position for the current node and insert it. Once all nodes have been inserted their sorted positions, return the sorted list.

Steps

Define a node struct from which lists will be created.

  • each value is an integer
  • each next is a pointer to the next node in the list A function creates a linked list, accepting an array of integers and an array length.
  • return early if the array is empty
  • create the head of the new linked list
    • allocate enough memory for the size of a list node
    • the value of head is assigned the first element from the input array
    • the next of head points to null (indicating the end of the list)
  • create a new node to track the current position while iterating to build the list
    • the current node begins with the value of head and points to newly allocated node
    • the newly allocated node being pointed to is then assigned the next value of the array and points to NULL (indicating the end of the list when no more values are left in the source array)
    • the node tracking current position now takes the value of newly built node
  • return the head of the list, representing the start of the linked list A function sorts the linked list, accepting a pointer to the head of the unsorted linked list.
  • return head early if the list is empty or has only one element
  • create a temporary sorted list head with an empty node
  • create a pointer to iterate through the original list
  • temporarily store the next node of the original list before re-linking in sorted order
  • iterate until finding the correct position to insert the current node
  • insert the current node into the sorted list
  • move to the next node in the original list and repeat until fully sorted
  • return the sorted list
Complexity Analysis

Time: O(n^2) Space: O(1)

Implementation

c (Iterative and Intuitive)

struct ListNode {
    int val;
    struct ListNode *next;
};

struct ListNode* linked_list(int arr[], int len) {
    if (len == 0) {
        return NULL;
    }

    struct ListNode* head = (struct ListNode*)malloc(sizeof(struct ListNode));
    head->val = arr[0];
    head->next = NULL;

    struct ListNode* curr = head;

    for (int i = 1; i < len; i++) {
        curr->next = (struct ListNode*)malloc(sizeof(struct ListNode));
        curr->next->val = arr[i];
        curr->next->next = NULL;

        curr = curr->next;
    }

    return head;
}

struct ListNode* insertion_sort_list(struct ListNode* head) {
    if (!head || !head->next) {
        return head;
    }

    struct ListNode* sorted_head = malloc(sizeof(struct ListNode));
    sorted_head->next = NULL;

    struct ListNode* current = head;
    while (current) {
        struct ListNode* next_node = current->next;
        struct ListNode* sorted_current = sorted_head;

        while (sorted_current->next && sorted_current->next->val < current->val) {
            sorted_current = sorted_current->next;
        }

        current->next = sorted_current->next;
        sorted_current->next = current;

       current = next_node;
    }

    struct ListNode* sorted_list = sorted_head->next;
    free(sorted_head);

    return sorted_list;
}

int main(void) {
    int arr[] = { 4, 2, 1, 3 };
    int len = sizeof(arr) / sizeof(arr[0]);
    struct ListNode* input_list = linked_list(arr, len);
    struct ListNode* solution = insertion_sort_list(input_list);

    struct ListNode* tmp = solution;
    printf("[");
    while (tmp != NULL) {
        printf(" %d", tmp->val);
        tmp = tmp->next;
    }
    printf(" ]\n");

    return 0;
}

go (Iterative and Intuitive)

type ListNode struct {
        Val  int
        Next *ListNode
}

func main() {
        arr := []int{4, 2, 1, 3}
        head := linkedList(arr)
        solution := insertionSortList(head)

        fmt.Printf("[")
        curr := solution
        for curr != nil {
                fmt.Printf("%d", curr.Val)
                curr = curr.Next
                if curr != nil {
                        fmt.Printf(" ")
                }
        }
        fmt.Printf("]\n")
}

func insertionSortList(head *ListNode) *ListNode {
        if head == nil {
                return head
        }

        sorted := &ListNode{}
        curr := head

        for curr != nil {
                prev := sorted
                next := curr.Next

                for prev.Next != nil && prev.Next.Val < curr.Val {
                        prev = prev.Next
                }

                curr.Next = prev.Next
                prev.Next = curr

                curr = next
        }
        return sorted.Next
}

func linkedList(arr []int) *ListNode {
        if len(arr) == 0 {
                return nil
        }

        head := &ListNode{Val: arr[0]}
        curr := head

        for _, j := range arr[1:] {
                curr.Next = &ListNode{Val: j}
                curr = curr.Next
        }

        return head
}

c# (Iterative and Intuitive)

namespace Solution
{
    public class ListNode
    {
        public int val;
        public ListNode? next;
        public ListNode(int val = 0, ListNode? next = null)
        {
            this.val = val;
            this.next = next;
        }
    }
    public class Program
    {
        public static void Main()
        {
            int[] arr = new int[] { 4, 2, 1, 3 };
            int len = arr.Length;

            ListNode input_list = LinkedList(arr, len);
            ListNode solution = InsertionSortList(input_list);

            Console.Write("[");
            ListNode curr = solution;
            while (curr != null)
            {
                Console.Write(curr.val);
                curr = curr.next!;
                if (curr != null)
                {
                    Console.Write(", ");
                }
            }
            Console.WriteLine("]");
        }

        public static ListNode LinkedList(int[] arr, int len)
        {
            if (len == 0)
            {
                return new ListNode();
            }

            ListNode head = new ListNode(arr[0]);
            ListNode curr = head;
            for (int i = 1; i < len; i++)
            {
                curr.next = new ListNode(arr[i]);
                curr = curr.next;
            }

            return head;
        }

        public static ListNode InsertionSortList(ListNode head)
        {
            if (head == null || head.next == null)
            {
                return head!;
            }

            ListNode sorted_head = new ListNode(0);
            ListNode curr = head;

            while (curr != null)
            {
                ListNode next_node = curr.next!;

                ListNode sorted_curr = sorted_head;
                while (sorted_curr.next != null && sorted_curr.next.val < curr.val)
                {
                    sorted_curr = sorted_curr.next;
                }

                curr.next = sorted_curr.next;
                sorted_curr.next = curr;

                curr = next_node;
            }

            return sorted_head.next!;
        }
    }
}