In this tutorial, we will write a Program to implement the Doubly Linked List data structure using the Kotlin programming language.
A doubly linked list is a complex type of linked list in which a node contains a pointer to the previous as well as the next node in the sequence. Therefore, in a doubly-linked list, a node consists of three parts: node data, a pointer to the next node in sequence (next pointer), and a pointer to the previous node (previous pointer).
Doubly Linked List Implementation in Kotlin
Let's Implement Doubly Linked List to perform the below operations:
- getFirst() - Get first element
- add() - add a new element
- get() - get the specific element
- set() - set the specific element r
- emoveFirst() - remove the first element
- removeLast() - remove the last element
- removeValue() - remove the value from Node
- addAll() - add all the elements
Here is the complete Kotlin program with output to implement the Doubly Linked List:
class DoublyLinkyList<E> {
private var size = 0
private var head: Node<E>? = null
private var tail: Node<E>? = null
private inner class Node<E> constructor(internal var prev: Node<E>?, internal var element: E, internal var next: Node<E>?)
fun getFirst() = head?.element
fun getLast() = tail?.element
fun removeFirst() = unlinkHead()
fun removeLast() = unlinkTail()
fun addFirst(element: E) {
linkHead(element)
}
fun addLast(element: E) {
linkTail(element)
}
fun add(element: E) {
linkTail(element)
}
fun <T> addAll(index: Int, arr: Array<T>): Boolean where T : E {
validatePositionIndex(index)
val numNew = arr.size
if (numNew == 0) return false
var pred: Node<E>?
var succ: Node<E>?
when (index) {
0 -> {
succ = head
pred = null
}
size -> {
succ = null
pred = tail
}
else -> {
succ = node(index)
pred = succ.prev
}
}
for (item in arr) {
val e = item as E
val newNode = Node<E>(pred, e, null)
if (pred == null)
head = newNode
else
pred.next = newNode
pred = newNode
}
if (succ == null) {
tail = pred
} else {
pred!!.next = succ
succ!!.prev = pred
}
size += numNew
return true
}
fun remove(element: E): Boolean {
var curr = head
while (curr != null) {
if (curr.element == element) {
unlink(curr)
return true
}
curr = curr.next
}
return false
}
fun clear() {
var x = head
while (x != null) {
val next = x.next
x.next = null
x.prev = null
x = next
}
tail = null
head = tail
size = 0
}
fun size() = size
operator fun contains(element: E) = indexOf(element) != -1
fun get(index: Int): E {
validateElementIndex(index)
return node(index).element
}
fun set(index: Int, element: E): E {
validateElementIndex(index)
val x = node(index)
val oldVal = x.element
x.element = element
return oldVal
}
fun add(index: Int, element: E) {
validatePositionIndex(index)
if (index == size) {
linkTail(element)
} else {
linkBefore(element, node(index))
}
}
fun remove(index: Int): E {
validateElementIndex(index)
return unlink(node(index))
}
fun indexOf(element: E): Int {
var index = 0
var x = head
while (x != null) {
if (element == x.element)
return index
index++
x = x.next
}
return -1
}
private fun linkHead(element: E) {
val h = head
val newNode = Node<E>(null, element, h)
head = newNode
if (h == null) {
tail = newNode
} else {
h.prev = newNode
}
size++
}
private fun linkTail(element: E) {
val t = tail
val newNode = Node<E>(t, element, null)
tail = newNode
if (t == null) {
head = newNode
} else {
t.next = newNode
}
size++
}
private fun linkBefore(element: E, succ: Node<E>) {
val pred = succ.prev
val newNode = Node(pred, element, succ)
succ.prev = newNode
if (pred == null) {
head = newNode
} else {
pred.next = newNode
}
size++
}
private fun unlinkHead() {
head?.let {
val next = it.next
it.next = null
head = next
if (next == null) {
tail = null
} else {
next.prev = null
}
size--
}
}
private fun unlinkTail() {
tail?.let {
val prev = it.prev
it.prev = null
tail = prev
if (prev == null) {
head = null
} else {
prev.next = null
}
size--
}
}
private fun unlink(curr: Node<E>): E {
val element = curr.element
val next = curr.next
val prev = curr.prev
if (prev == null) {
head = next
} else {
prev.next = next
curr.prev = null
}
if (next == null) {
tail = prev
} else {
next.prev = prev
curr.next = null
}
size--
return element
}
private fun node(index: Int): Node<E> {
if (index < size shr 1) {
var x = head
for (i in 0 until index)
x = x!!.next
return x!!
} else {
var x = tail
for (i in size - 1 downTo index + 1)
x = x!!.prev
return x!!
}
}
private fun validateElementIndex(index: Int) {
if (index < 0 || index >= size)
throw IndexOutOfBoundsException(outOfBoundsMsg(index))
}
private fun validatePositionIndex(index: Int) {
if (index < 0 && index > size)
throw IndexOutOfBoundsException(outOfBoundsMsg(index))
}
private fun outOfBoundsMsg(index: Int): String {
return "Index: $index, Size: $size"
}
override fun toString(): String {
var curr = head
if (curr == null) return "[]"
else {
val sb = StringBuilder()
sb.append('[')
while (curr != null) {
sb.append(curr.element)
curr = curr.next
if (curr?.element == null) {
sb.append(']')
} else {
sb.append(',').append(' ')
}
}
return sb.toString()
}
}
}
fun main(args: Array<String>) {
val doublyLinkyList = DoublyLinkyList<String>()
println("First item of the linky list is - ${doublyLinkyList.getFirst()}")
println("Last item of the linky list is - ${doublyLinkyList.getLast()}")
println()
doublyLinkyList.add("Kotlin")
println("First item of the linky list is - ${doublyLinkyList.getFirst()}")
println("Last item of the linky list is - ${doublyLinkyList.getLast()}")
println()
doublyLinkyList.add("Java")
println("First item of the linky list is - ${doublyLinkyList.getFirst()}")
println("Last item of the linky list is - ${doublyLinkyList.getLast()}")
doublyLinkyList.add("C#")
doublyLinkyList.add("Python")
doublyLinkyList.add("JavaScript")
println()
println("Elements at doublyLinkyList - $doublyLinkyList")
doublyLinkyList.remove("JavaScript")
println("Elements at doublyLinkyList after removing JavaScript - $doublyLinkyList")
doublyLinkyList.remove("Kotlin")
println("Elements at doublyLinkyList after removing Kotlin - $doublyLinkyList")
doublyLinkyList.remove("C#")
println("Elements at doublyLinkyList after removing C# - $doublyLinkyList")
doublyLinkyList.remove("Java")
println("Elements at doublyLinkyList after removing Java - $doublyLinkyList")
doublyLinkyList.remove("Python")
println("Elements at doublyLinkyList after removing Python - $doublyLinkyList")
testGetFirst()
testAdd()
testGet()
testSet()
testRemoveFirst()
testRemoveLast()
testRemoveValue()
testAddAll()
}
fun testGetFirst() {
println()
println("==================================")
println("getFirst method testing started")
val doublyLinkyList = DoublyLinkyList<String>()
println(doublyLinkyList.getFirst() == null)
doublyLinkyList.add("Kotlin")
println(doublyLinkyList.getFirst() == "Kotlin")
doublyLinkyList.add("Java")
println(doublyLinkyList.getFirst() == "Kotlin")
doublyLinkyList.add("Python")
println(doublyLinkyList.getFirst() == "Kotlin")
doublyLinkyList.add(0, "Python")
println(doublyLinkyList.getFirst() == "Python")
doublyLinkyList.add(1, "JavaScript")
println(doublyLinkyList.getFirst() == "Python")
doublyLinkyList.set(0, "JavaScript")
println(doublyLinkyList.getFirst() == "JavaScript")
doublyLinkyList.set(1, "Kotlin")
println(doublyLinkyList.getFirst() == "JavaScript")
doublyLinkyList.addFirst("Kotlin")
println(doublyLinkyList.getFirst() == "Kotlin")
doublyLinkyList.addLast("JavaScript")
println(doublyLinkyList.getFirst() == "Kotlin")
println("getFirst method testing ended")
println("==================================")
println()
doublyLinkyList.clear()
println("Elements at LinkyList - $doublyLinkyList")
doublyLinkyList.addFirst("Kotlin")
println("Elements at LinkyList - $doublyLinkyList")
doublyLinkyList.addFirst("Kotlin")
println("Elements at LinkyList - $doublyLinkyList")
doublyLinkyList.addFirst("Java")
println("Elements at LinkyList - $doublyLinkyList")
doublyLinkyList.addFirst("Python")
println("Elements at LinkyList - $doublyLinkyList")
}
fun testAdd() {
println()
println("==================================")
println("testAdd method testing started")
val doublyLinkyList = DoublyLinkyList<String>()
doublyLinkyList.add("Kotlin")
doublyLinkyList.add("Java")
doublyLinkyList.add("C#")
doublyLinkyList.add("C")
doublyLinkyList.add("C++")
println("Elements at LinkyList - $doublyLinkyList")
println()
doublyLinkyList.add(1, "JavaScript")
println("Elements at LinkyList - $doublyLinkyList")
println()
doublyLinkyList.add(2, "TypeScript")
println("Elements at LinkyList - $doublyLinkyList")
println()
doublyLinkyList.add(3, "CofeeScript")
println("Elements at LinkyList - $doublyLinkyList")
println()
doublyLinkyList.add(7, "MongoDB")
println("Elements at LinkyList - $doublyLinkyList")
println()
doublyLinkyList.add(0, "SQL")
println("Elements at LinkyList - $doublyLinkyList")
println("testAdd method testing started")
println("==================================")
}
fun testGet() {
println()
println("=================================")
println("Testing get started")
val doublyLinkyList = DoublyLinkyList<String>()
doublyLinkyList.add("Kotlin")
doublyLinkyList.add("Java")
doublyLinkyList.add("C#")
doublyLinkyList.add("C")
doublyLinkyList.add("C++")
println("0th Index - ${doublyLinkyList.get(0)}")
println("1st Index - ${doublyLinkyList.get(1)}")
println("2nd Index - ${doublyLinkyList.get(2)}")
println("3rd Index - ${doublyLinkyList.get(3)}")
println("4th Index - ${doublyLinkyList.get(4)}")
println("Testing get ended")
println("=================================")
}
fun testSet() {
println()
println("=================================")
println("Testing set started")
val doublyLinkyList = DoublyLinkyList<String>()
doublyLinkyList.add("Kotlin")
doublyLinkyList.add("Java")
doublyLinkyList.add("C#")
doublyLinkyList.add("C")
doublyLinkyList.add("C++")
println("0th Index - ${doublyLinkyList.set(0, "Edited Kotlin")}")
println("1st Index - ${doublyLinkyList.set(1, "Edited Java")}")
println("2nd Index - ${doublyLinkyList.set(2, "Edited C#")}")
println("3rd Index - ${doublyLinkyList.set(3, "Edited C")}")
println("4th Index - ${doublyLinkyList.set(4, "Edited C++")}")
println("Final list - $doublyLinkyList")
println("Testing set ended")
println("=================================")
}
fun testRemoveFirst() {
println()
println("=================================")
println("Testing removeFirst started")
val doublyLinkyList = DoublyLinkyList<String>()
doublyLinkyList.add("Kotlin")
doublyLinkyList.add("Java")
doublyLinkyList.add("C#")
doublyLinkyList.add("C")
doublyLinkyList.add("C++")
println("List - $doublyLinkyList")
doublyLinkyList.removeFirst()
println("List - $doublyLinkyList")
doublyLinkyList.removeFirst()
println("List - $doublyLinkyList")
doublyLinkyList.removeFirst()
println("List - $doublyLinkyList")
doublyLinkyList.removeFirst()
println("List - $doublyLinkyList")
println("Testing removeFirst ended")
println("=================================")
}
fun testRemoveLast() {
println()
println("=================================")
println("Testing removeLast started")
val doublyLinkyList = DoublyLinkyList<String>()
doublyLinkyList.add("Kotlin")
doublyLinkyList.add("Java")
doublyLinkyList.add("C#")
doublyLinkyList.add("C")
doublyLinkyList.add("C++")
println("List - $doublyLinkyList")
doublyLinkyList.removeLast()
println("List - $doublyLinkyList")
doublyLinkyList.removeLast()
println("List - $doublyLinkyList")
doublyLinkyList.removeLast()
println("List - $doublyLinkyList")
doublyLinkyList.removeLast()
println("List - $doublyLinkyList")
doublyLinkyList.removeLast()
println("List - $doublyLinkyList")
println("Testing removeLast ended")
println("=================================")
}
fun testRemoveValue() {
println()
println("=================================")
println("Testing testRemoveValue started")
val doublyLinkyList = DoublyLinkyList<String>()
doublyLinkyList.add("Kotlin")
doublyLinkyList.add("Java")
doublyLinkyList.add("C#")
doublyLinkyList.add("C")
doublyLinkyList.add("C++")
println("JavaScript" in doublyLinkyList)
println("Kotlin" in doublyLinkyList)
println("List - $doublyLinkyList")
doublyLinkyList.remove("Java")
println("List - $doublyLinkyList")
doublyLinkyList.remove("Kotlin")
println("List - $doublyLinkyList")
doublyLinkyList.remove("JavaScript")
println("List - $doublyLinkyList")
doublyLinkyList.remove("Python")
println("List - $doublyLinkyList")
println("Testing testRemoveValue ended")
println("=================================")
}
fun testAddAll() {
println()
println("=================================")
println("Testing testAddAll started")
val doublyLinkyList = DoublyLinkyList<String>()
// Add few elements at begining of the linkedlist
doublyLinkyList.addAll(0, arrayOf<String>("C", "C++"))
println("List - $doublyLinkyList")
doublyLinkyList.addAll(0, arrayOf<String>("Java", "Kotlin"))
println("List - $doublyLinkyList")
// Add few elements at middle of the linkedlist
doublyLinkyList.addAll(2, arrayOf<String>("Python", "R"))
println("List - $doublyLinkyList")
// Add few elements at end of the linkedlist
doublyLinkyList.addAll(doublyLinkyList.size(), arrayOf<String>("C#", "MATLAB"))
println("List - $doublyLinkyList")
println("Testing testAddAll ended")
println("=================================")
}
Output:
First item of the linky list is - null
Last item of the linky list is - null
First item of the linky list is - Kotlin
Last item of the linky list is - Kotlin
First item of the linky list is - Kotlin
Last item of the linky list is - Java
Elements at doublyLinkyList - [Kotlin, Java, C#, Python, JavaScript]
Elements at doublyLinkyList after removing JavaScript - [Kotlin, Java, C#, Python]
Elements at doublyLinkyList after removing Kotlin - [Java, C#, Python]
Elements at doublyLinkyList after removing C# - [Java, Python]
Elements at doublyLinkyList after removing Java - [Python]
Elements at doublyLinkyList after removing Python - []
==================================
getFirst method testing started
true
true
true
true
true
true
true
true
true
true
getFirst method testing ended
==================================
Elements at LinkyList - []
Elements at LinkyList - [Kotlin]
Elements at LinkyList - [Kotlin, Kotlin]
Elements at LinkyList - [Java, Kotlin, Kotlin]
Elements at LinkyList - [Python, Java, Kotlin, Kotlin]
==================================
testAdd method testing started
Elements at LinkyList - [Kotlin, Java, C#, C, C++]
Elements at LinkyList - [Kotlin, JavaScript, Java, C#, C, C++]
Elements at LinkyList - [Kotlin, JavaScript, TypeScript, Java, C#, C, C++]
Elements at LinkyList - [Kotlin, JavaScript, TypeScript, CofeeScript, Java, C#, C, C++]
Elements at LinkyList - [Kotlin, JavaScript, TypeScript, CofeeScript, Java, C#, C, MongoDB, C++]
Elements at LinkyList - [SQL, Kotlin, JavaScript, TypeScript, CofeeScript, Java, C#, C, MongoDB, C++]
testAdd method testing started
==================================
=================================
Testing get started
0th Index - Kotlin
1st Index - Java
2nd Index - C#
3rd Index - C
4th Index - C++
Testing get ended
=================================
=================================
Testing set started
0th Index - Kotlin
1st Index - Java
2nd Index - C#
3rd Index - C
4th Index - C++
Final list - [Edited Kotlin, Edited Java, Edited C#, Edited C, Edited C++]
Testing set ended
=================================
=================================
Testing removeFirst started
List - [Kotlin, Java, C#, C, C++]
List - [Java, C#, C, C++]
List - [C#, C, C++]
List - [C, C++]
List - [C++]
Testing removeFirst ended
=================================
=================================
Testing removeLast started
List - [Kotlin, Java, C#, C, C++]
List - [Kotlin, Java, C#, C]
List - [Kotlin, Java, C#]
List - [Kotlin, Java]
List - [Kotlin]
List - []
Testing removeLast ended
=================================
=================================
Testing testRemoveValue started
false
true
List - [Kotlin, Java, C#, C, C++]
List - [Kotlin, C#, C, C++]
List - [C#, C, C++]
List - [C#, C, C++]
List - [C#, C, C++]
Testing testRemoveValue ended
=================================
=================================
Testing testAddAll started
List - [C, C++]
List - [Java, Kotlin, C, C++]
List - [Java, Kotlin, Python, R, C, C++]
List - [Java, Kotlin, Python, R, C, C++, C#, MATLAB]
Testing testAddAll ended
=================================
Related Data Structures and Algorithms in Kotlin
- Stack Data Structure Implementation in Kotlin
- Queue Data Structure Implementation in Kotlin
- Deque Implementation in Kotlin
- Singly Linked List Implementation in Kotlin
- Doubly Linked List Implementation in Kotlin
- Circular Linked List Implementation in Kotlin
- Bubble Sort Algorithm in Kotlin
- Heap Sort Algorithm in Kotlin
- Insertion Sort Algorithm in Kotlin
- Merge Sort Algorithm in Kotlin
- Quick Sort Algorithm in Kotlin
- Selection Sort Algorithm in Kotlin
- Stack Data Structure Implementation in Kotlin
- Queue Data Structure Implementation in Kotlin
- Deque Implementation in Kotlin
- Singly Linked List Implementation in Kotlin
- Doubly Linked List Implementation in Kotlin
- Circular Linked List Implementation in Kotlin
- Bubble Sort Algorithm in Kotlin
- Heap Sort Algorithm in Kotlin
- Insertion Sort Algorithm in Kotlin
- Merge Sort Algorithm in Kotlin
- Quick Sort Algorithm in Kotlin
- Selection Sort Algorithm in Kotlin
Comments
Post a Comment
Leave Comment