数据结构和算法,双向链表的实现增删改查(kotlin版)
1.定义接口,我们需要实现的方法
interface LinkedListAction<E> {
fun push(e: E)
fun size(): Int
fun getValue(index: Int): E?
fun insert(index: Int,e: E)
fun remove(index: Int)
}
2.定义节点,表示每个链表节点。
data class Node<E>(var next: Node<E>? = null, var prev: Node<E>? = null, var value: E)
3.push(e: E),链表尾部新增一个节点
override fun push(e: E) {
linkLast(e)
len++
}
private fun linkLast(e: E) {
var l = last
val newNode = Node(null, last, e)
last = newNode
if (head != null) {
l?.next = newNode
} else {
head = newNode
}
}
4.size(): Int,返回链表的长度
override fun size(): Int {
return len
}
5.getValue(index: Int): E?,获取列表的value值
override fun getValue(index: Int): E? {
if (index < 0 || index >= len) {
throw ArrayIndexOutOfBoundsException("数组越界.....")
}
return node(index)?.value
}
private fun node(index: Int): Node<E>? {
if (index < (len shr 1)) {
var cur = head
for (i in 0 until index) {
cur = cur?.next
}
return cur
} else {
var cur = last
for (i in (len - 1) downTo index + 1) {
cur = cur?.prev
}
return cur
}
}
6.insert(index: Int,e: E),从任意位置插入一个节点
override fun insert(index: Int, e: E) {
if (index < 0 || index > len) {
throw ArrayIndexOutOfBoundsException("数组越界.....")
}
if (index == len) {
linkLast(e)
} else {
linkBefore(node(index), e)
}
len++
}
private fun linkLast(e: E) {
var l = last
val newNode = Node(null, last, e)
last = newNode
if (head != null) {
l?.next = newNode
} else {
head = newNode
}
}
private fun linkBefore(cur: Node<E>?, e: E) {
val prev = cur?.prev
val newNode = Node(cur, prev, e)
cur?.prev = newNode
if (prev != null) {
prev.next = newNode
} else {
head = newNode
}
}
7.remove(index: Int),任意位置删除一个节点
override fun remove(index: Int) {
if (index < 0 || index >= len) {
throw ArrayIndexOutOfBoundsException("数组越界.....")
}
unlike(node(index))
len--
}
private fun unlike(cur: Node<E>?): E? {
val value = cur?.value
val prev = cur?.prev
val next = cur?.next
if (prev != null) {
prev.next = next
} else {
head = next
}
if (next != null) {
next.prev = prev
} else {
last = prev
}
return value
}
8.完整Demo
package day1
class LinkedList<E> : LinkedListAction<E> {
private var head: Node<E>? = null
private var last: Node<E>? = null
private var len = 0
override fun push(e: E) {
linkLast(e)
len++
}
private fun linkLast(e: E) {
var l = last
val newNode = Node(null, last, e)
last = newNode
if (head != null) {
l?.next = newNode
} else {
head = newNode
}
}
private fun node(index: Int): Node<E>? {
if (index < (len shr 1)) {
var cur = head
for (i in 0 until index) {
cur = cur?.next
}
return cur
} else {
var cur = last
for (i in (len - 1) downTo index + 1) {
cur = cur?.prev
}
return cur
}
}
override fun size(): Int {
return len
}
override fun getValue(index: Int): E? {
if (index < 0 || index >= len) {
throw ArrayIndexOutOfBoundsException("数组越界.....")
}
return node(index)?.value
}
override fun insert(index: Int, e: E) {
if (index < 0 || index > len) {
throw ArrayIndexOutOfBoundsException("数组越界.....")
}
if (index == len) {
linkLast(e)
} else {
linkBefore(node(index), e)
}
len++
}
private fun linkBefore(cur: Node<E>?, e: E) {
val prev = cur?.prev
val newNode = Node(cur, prev, e)
cur?.prev = newNode
if (prev != null) {
prev.next = newNode
} else {
head = newNode
}
}
override fun remove(index: Int) {
if (index < 0 || index >= len) {
throw ArrayIndexOutOfBoundsException("数组越界.....")
}
unlike(node(index))
len--
}
private fun unlike(cur: Node<E>?): E? {
val value = cur?.value
val prev = cur?.prev
val next = cur?.next
if (prev != null) {
prev.next = next
} else {
head = next
}
if (next != null) {
next.prev = prev
} else {
last = prev
}
return value
}
}