LinkedList: implement insert and reverse
This commit is contained in:
parent
3759d5eb84
commit
e43fc8e7f0
2 changed files with 176 additions and 1 deletions
|
@ -43,6 +43,43 @@ class LinkedList<T> : Iterable<Node<T>> {
|
|||
size += 1
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts an element at the given position.
|
||||
*/
|
||||
fun insert(value: T, position: Int) {
|
||||
// handle invalid position
|
||||
if (position < 0 || position > size) {
|
||||
throw IllegalArgumentException("invalid position given")
|
||||
}
|
||||
// handle insert last
|
||||
if (position == size) {
|
||||
append(value)
|
||||
return
|
||||
}
|
||||
// handle insert first
|
||||
if (position == 0) {
|
||||
val newNode = Node(value, head)
|
||||
head = newNode
|
||||
size += 1
|
||||
return
|
||||
}
|
||||
var currentPosition = 0
|
||||
var currentNode: Node<T>? = head
|
||||
var previousNode: Node<T>? = null
|
||||
// search for position to insert at
|
||||
while (true) {
|
||||
if (currentPosition == position) {
|
||||
val newNode = Node(value, currentNode)
|
||||
previousNode?.next = newNode
|
||||
size += 1
|
||||
break
|
||||
}
|
||||
currentPosition += 1
|
||||
previousNode = currentNode
|
||||
currentNode = currentNode?.next
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns from the list
|
||||
*/
|
||||
|
@ -64,7 +101,7 @@ class LinkedList<T> : Iterable<Node<T>> {
|
|||
*/
|
||||
fun delete(position: Int) {
|
||||
if (size == 0 || position < 0 || position >= size) {
|
||||
return
|
||||
throw IllegalArgumentException("invalid position given")
|
||||
}
|
||||
// delete head
|
||||
if (position == 0) {
|
||||
|
@ -84,8 +121,10 @@ class LinkedList<T> : Iterable<Node<T>> {
|
|||
previousNode = currentNode
|
||||
currentNode = currentNode?.next
|
||||
currentPosition += 1
|
||||
// we found element at position N which is about to get deleted
|
||||
if (currentPosition == position) {
|
||||
previousNode!!.next = currentNode?.next
|
||||
// we deleted the tail, so we need to update tail var.
|
||||
if (currentPosition == size - 1) {
|
||||
tail = previousNode
|
||||
}
|
||||
|
@ -109,6 +148,32 @@ class LinkedList<T> : Iterable<Node<T>> {
|
|||
return size
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverses the list in place.
|
||||
*/
|
||||
fun reverse() {
|
||||
if (size == 1) {
|
||||
return
|
||||
}
|
||||
tail = head
|
||||
var currentNode = head
|
||||
var previousNode: Node<T>? = null
|
||||
var next = head
|
||||
// we iterate through the list and updates next accordingly, until we reach the tail.
|
||||
while (next != null) {
|
||||
// save the next
|
||||
next = currentNode?.next
|
||||
// current node's next will be set to previous node.
|
||||
currentNode?.next = previousNode
|
||||
// track previous node by settings it to current node
|
||||
previousNode = currentNode
|
||||
// track the current node by setting it to next
|
||||
currentNode = next
|
||||
}
|
||||
// update the head
|
||||
head = previousNode
|
||||
}
|
||||
|
||||
/**
|
||||
* NodeIterator that iterates over linked list nodes.
|
||||
*/
|
||||
|
|
|
@ -150,6 +150,21 @@ class LinkedListTest {
|
|||
assertEquals("Second", linkedList.getLast())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun deleteInvalidPosition() {
|
||||
// Setup
|
||||
val linkedList = LinkedList<String>()
|
||||
linkedList.append("First")
|
||||
|
||||
// Test
|
||||
assertThrows(IllegalArgumentException::class.java) {
|
||||
linkedList.delete(-1)
|
||||
}
|
||||
assertThrows(IllegalArgumentException::class.java) {
|
||||
linkedList.delete(99)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun toJavaList() {
|
||||
// Setup
|
||||
|
@ -164,4 +179,99 @@ class LinkedListTest {
|
|||
// Assert
|
||||
assertContentEquals(listOf("First", "Second", "Third"), result)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun insertFirst() {
|
||||
// Setup
|
||||
val linkedList = LinkedList<String>()
|
||||
linkedList.append("Second")
|
||||
|
||||
// Test
|
||||
linkedList.insert("First", 0)
|
||||
|
||||
// Assert
|
||||
assertContentEquals(listOf("First", "Second"), linkedList.toJavaList())
|
||||
assertEquals("First", linkedList.getFirst())
|
||||
assertEquals("Second", linkedList.getLast())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun insertLast() {
|
||||
// Setup
|
||||
val linkedList = LinkedList<String>()
|
||||
linkedList.append("First")
|
||||
|
||||
// Test
|
||||
linkedList.insert("Second", linkedList.size())
|
||||
|
||||
// Assert
|
||||
assertContentEquals(listOf("First", "Second"), linkedList.toJavaList())
|
||||
assertEquals("First", linkedList.getFirst())
|
||||
assertEquals("Second", linkedList.getLast())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun insertMiddle() {
|
||||
// Setup
|
||||
val linkedList = LinkedList<String>()
|
||||
linkedList.append("First")
|
||||
linkedList.append("Second")
|
||||
|
||||
// Test
|
||||
linkedList.insert("Middle", linkedList.size() - 1)
|
||||
|
||||
// Assert
|
||||
assertContentEquals(listOf("First", "Middle", "Second"), linkedList.toJavaList())
|
||||
assertEquals("First", linkedList.getFirst())
|
||||
assertEquals("Second", linkedList.getLast())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun reverseOneElement() {
|
||||
// Setup
|
||||
val linkedList = LinkedList<String>()
|
||||
linkedList.append("First")
|
||||
|
||||
// Test
|
||||
linkedList.reverse()
|
||||
|
||||
// Assert
|
||||
assertContentEquals(listOf("First"), linkedList.toJavaList())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun reverseTwoElements() {
|
||||
// Setup
|
||||
val linkedList = LinkedList<String>()
|
||||
linkedList.append("First")
|
||||
linkedList.append("Second")
|
||||
|
||||
// Test
|
||||
linkedList.reverse()
|
||||
|
||||
// Assert
|
||||
assertContentEquals(listOf("Second", "First"), linkedList.toJavaList())
|
||||
assertEquals("Second", linkedList.getFirst())
|
||||
assertEquals("First", linkedList.getLast())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun reverseFiveElements() {
|
||||
// Setup
|
||||
val linkedList = LinkedList<String>()
|
||||
linkedList.append("First")
|
||||
linkedList.append("Second")
|
||||
linkedList.append("Third")
|
||||
linkedList.append("Fourth")
|
||||
linkedList.append("Fifth")
|
||||
|
||||
|
||||
// Test
|
||||
linkedList.reverse()
|
||||
|
||||
// Assert
|
||||
assertContentEquals(listOf("Fifth", "Fourth", "Third", "Second", "First"), linkedList.toJavaList())
|
||||
assertEquals("Fifth", linkedList.getFirst())
|
||||
assertEquals("First", linkedList.getLast())
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue