To implement merge sort on a linked list, you can follow these steps:
- Define a
Nodeclass to represent a node in the linked list. Each node should have adataproperty to store its value, and anextproperty to point to the next node in the list. - Define a
mergeSortfunction that takes the head of the linked list as an argument and returns the sorted linked list. - In the
mergeSortfunction, first, check if the linked list is empty or has only one element, in which case it is already sorted and can be returned as is. - Otherwise, divide the linked list into two halves using a
splitfunction that uses the slow and fast pointer technique. - Recursively call the
mergeSortfunction on the two halves to sort them. - Merge the two sorted halves using a
mergefunction. Themergefunction takes two sorted linked lists as arguments and returns the merged sorted linked list. - In the
mergefunction, create a dummy node to act as the head of the merged list. Traverse the two linked lists simultaneously, comparing the values of the nodes at each step and appending the smaller node to the merged list. - After one of the lists is exhausted, append the remaining nodes of the other list to the merged list.
Kotlin
class Node(var data: Int, var next: Node? = null)
fun mergeSort(head: Node?): Node? {
// Check for empty list or single element list
if (head == null || head.next == null) {
return head
}
// Divide the list into two halves
val (left, right) = split(head)
// Recursively sort the two halves
val sortedLeft = mergeSort(left)
val sortedRight = mergeSort(right)
// Merge the two sorted halves
return merge(sortedLeft, sortedRight)
}
fun split(head: Node?): Pair<Node?, Node?> {
var slow = head
var fast = head?.next
while (fast != null) {
fast = fast.next?.next
if (fast != null) {
slow = slow?.next
}
}
val left = head
val right = slow?.next
slow?.next = null
return Pair(left, right)
}
fun merge(left: Node?, right: Node?): Node? {
// Create a dummy node to act as the head of the merged list
val dummy = Node(0)
var current = dummy
var leftCurrent = left
var rightCurrent = right
// Traverse the two linked lists simultaneously and append the smaller node to the merged list
while (leftCurrent != null && rightCurrent != null) {
if (leftCurrent.data < rightCurrent.data) {
current.next = leftCurrent
leftCurrent = leftCurrent.next
} else {
current.next = rightCurrent
rightCurrent = rightCurrent.next
}
current = current.next!!
}
// Append the remaining nodes of the other list to the merged list
if (leftCurrent != null) {
current.next = leftCurrent
} else {
current.next = rightCurrent
}
return dummy.next
}
// Example usage
fun main() {
// Create an unsorted linked list
val head = Node(3)
head.next = Node(2)
head.next?.next = Node(1)
head.next?.next?.next = Node(4)
// Sort the linked list using merge sort
val sortedList = mergeSort(head)
// Print the sorted linked list
var current = sortedList
while (current != null) {
print("${current.data} ")
current = current.next
}
}The linked list before sorting : 3 2 1 4
Output : 1 2 3 4