链表
- 链表是一个物理结构(非逻辑结构),类似于数组
- 数组需要一段连续的内存区间,而链表是零散的
- 链表节点的数据结构{value, next?, prev?}
创建链表代码
interface ILinkListNode {
value: number
next?: ILinkListNode
}
function createLinkList(arr: number[]): ILinkListNode {
const length = arr.length
if (length === 0) {
throw new Error('array is empty')
}
let curNode:ILinkListNode = { value: arr[length - 1] }
if (length === 1) return curNode
for (let i = arr[length - 2]; i >= 0; i--) {
curNode = {
value: arr[i],
next: curNode,
}
}
return curNode
}
const arr = [1, 2, 3, 4, 5]
const list = createLinkList(arr)
console.info(list)
链表vs数组
- 都是有序结构
- 链表:查询慢O(n),新增和删除快O(1)
- 数组:查询快O(1),新增和删除慢O(n)
前端在链表的应用
解题思路
- 反转,即节点next指向前一个节点
- 但这很容易造成nextNode的丢失
- 需要三个指针 prevNode curNode nextNode
反转单向链表代码:
interface ILinkListNode {
value: number
next?: ILinkListNode
}
function reverseLinkList(listNode: ILinkListNode): ILinkListNode {
// 定义三个指针
let prevNode: ILinkListNode | undefined = undefined
let curNode: ILinkListNode | undefined = undefined
let nextNode: ILinkListNode | undefined = listNode
// 以nextNode为主,遍历列表
while (nextNode) {
// 第一个元素,删掉next,防止循环引用
if (curNode && !prevNode) {
delete curNode.next
}
// 反转指针
if (curNode && nextNode) {
curNode.next = prevNode
}
prevNode = curNode
curNode = nextNode
nextNode = nextNode?.next
}
// 最后一个的补充:当nextNode为空时,此时 curNode 尚未设置next
curNode!.next = prevNode
return curNode!
}
结果:
全部代码:
interface ILinkListNode {
value: number
next?: ILinkListNode
}
function reverseLinkList(listNode: ILinkListNode): ILinkListNode {
// 定义三个指针
let prevNode: ILinkListNode | undefined = undefined
let curNode: ILinkListNode | undefined = undefined
let nextNode: ILinkListNode | undefined = listNode
// 以nextNode为主,遍历列表
while (nextNode) {
// 第一个元素,删掉next,防止循环引用
if (curNode && !prevNode) {
delete curNode.next
}
// 反转指针
if (curNode && nextNode) {
curNode.next = prevNode
}
prevNode = curNode
curNode = nextNode
nextNode = nextNode?.next
}
// 最后一个的补充:当nextNode为空时,此时 curNode 尚未设置next
curNode!.next = prevNode
return curNode!
}
function createLinkList(arr: number[]): ILinkListNode {
const length = arr.length
if (length === 0) {
throw new Error('array is empty')
}
let curNode: ILinkListNode = { value: arr[length - 1] }
if (length === 1) return curNode
for (let i = arr[length - 2]; i >= 0; i--) {
curNode = {
value: arr[i],
next: curNode,
}
}
return curNode
}
const arr = [1, 2, 3, 4, 5]
const list = createLinkList(arr)
console.log(list)
const list1 = reverseLinkList(list)
console.log(list1)