- Published on
手动实现一个链表结构
- Authors
- Name
- Et cetera
实现链表
LinkedList.ts
interface IList<T> {
// peek
peek(): T | undefined;
// 判断是否为空
isEmpty(): boolean;
// 元素个数
// get size(): number // 加了get关键字后调用size方法时,不用queue.size(),而可以直接queue.size直接调用
size(): number;
}
interface ILinkedList<T> extends IList<T> {
append(value: T): void
traverse(): void
insert(value: T, position: number): boolean
removeAt(position: number): T | null
get(position: number): T | null
update(value: T, position: number): boolean
indexOf(value: T): number
remove(value: T): T | null
}
// 1.创建Node节点类
class Node<T> {
value: T
next: Node<T> | null = null
constructor(value: T) {
this.value = value
}
}
// 2.创建LinkedList的类
class LinkedList<T> implements ILinkedList<T> {
private head: Node<T> | null = null
private length: number = 0
size() {
return this.length
}
peek(): T | undefined {
return this.head?.value
}
// 封装私有方法
// 根据position获取到当前的节点(不是节点的value, 而是获取节点)
private getNode(position: number): Node<T> | null {
let index = 0
let current = this.head
while (index++ < position && current) {
current = current.next
}
return current
}
// 追加节点
append(value: T) {
// 1.根据value创建一个新节点
const newNode = new Node(value)
// 2.判断this.head是否为null
if (!this.head) {
this.head = newNode
} else {
let current = this.head
while (current.next) {
current = current.next
}
// current肯定是指向最后一个节点的
current.next = newNode
}
// 3.size++
this.length++
}
// 遍历链表的方法
traverse() {
const values: T[] = []
let current = this.head
while (current) {
values.push(current.value)
current = current.next
}
console.log(values.join('->'))
}
// 插入方法:
insert(value: T, position: number): boolean {
// 1.越界的判断
if (position < 0 || position > this.length) return false
// 2.根据value创建新的节点
const newNode = new Node(value)
// 3.判断是否需要插入头部
if (position === 0) {
newNode.next = this.head
this.head = newNode
} else {
const previous = this.getNode(position - 1)
newNode.next = previous!.next
previous!.next = newNode
}
this.length++
return true
}
// 删除方法:
removeAt(position: number): T | null {
// 1.越界的判断
if (position < 0 || position >= this.length) return null
// 2.判断是否是删除第一个节点
let current = this.head
if (position === 0) {
this.head = current?.next ?? null
} else {
// 重构成如下代码
const previous = this.getNode(position - 1)
// 需要给current重新赋值
current = previous!.next
// 找到需要的节点
previous!.next = previous?.next?.next ?? null
}
this.length--
return current?.value ?? null
}
// 获取方法:
get(position: number): T | null {
// 越界问题
if (position < 0 || position >= this.length) return null
// 2.查找元素, 并且范围元素
return this.getNode(position)?.value ?? null
}
// 更新方法:
update(value: T, position: number): boolean {
if (position < 0 || position >= this.length) return false
// 获取对应位置的节点, 直接更新即可
const currentNode = this.getNode(position)
currentNode!.value = value
return true
}
// 根据值, 获取对应位置的索引
indexOf(value: T): number {
// 从第一个节点开始, 向后遍历
let current = this.head
let index = 0
while (current) {
if (current.value === value) {
return index
}
current = current.next
index++
}
return -1
}
// 删除方法: 根据value删除节点
remove(value: T): T | null {
const index = this.indexOf(value)
return this.removeAt(index)
}
// 判读单链表是否为空的方法
isEmpty() {
return this.length === 0
}
}