-
Notifications
You must be signed in to change notification settings - Fork 32
/
Copy pathLinkedList.ts
125 lines (104 loc) · 2.97 KB
/
LinkedList.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
/* eslint-disable @typescript-eslint/no-non-null-assertion */
import assert from 'assert'
import { LinkedListNode } from './LinkedListNode'
/**
* 链表实现的双端队列
*/
class LinkedList<E = number> {
/** 哨兵 */
readonly root: LinkedListNode<E>
private _size = 0
/**
* 初始化双向链表,判断节点时 next/pre 若为 root,则表示 next/pre 为空
*/
constructor(iterable?: Iterable<E>) {
this.root = new LinkedListNode<E>(undefined)
this.root.pre = this.root
this.root.next = this.root
for (const item of iterable || []) {
this.push(item)
this._size++
}
}
unshift(val: E): void {
this.root.insertAfter(new LinkedListNode(val))
this._size++
}
shift(): E | undefined {
if (this._isEmpty()) return undefined
this._size--
// eslint-disable-next-line prefer-destructuring
const next = this.root.next
return next ? next.remove().value : undefined
}
push(val: E): void {
this.root.insertBefore(new LinkedListNode(val))
this._size++
}
pop(): E | undefined {
if (this._isEmpty()) return undefined
this._size--
// eslint-disable-next-line prefer-destructuring
const pre = this.root.pre
return pre ? pre.remove().value : undefined
}
first(): E | undefined {
// eslint-disable-next-line prefer-destructuring
const next = this.root.next
return next ? next.value : undefined
}
last(): E | undefined {
// eslint-disable-next-line prefer-destructuring
const pre = this.root.pre
return pre ? pre.value : undefined
}
toString(): string {
return `${[...this]}`
}
insert(node: LinkedListNode<E>, cur: E): LinkedListNode<E> {
const newNode = new LinkedListNode(cur)
node.insertBefore(newNode)
this._size++
return newNode
}
erase(node: LinkedListNode<E>): void {
node.remove()
this._size--
}
// eslint-disable-next-line generator-star-spacing
*[Symbol.iterator](): IterableIterator<E> {
let node = this.root.next!
while (node !== this.root) {
yield node.value!
node = node.next!
}
}
get length(): number {
return this._size
}
private _isEmpty(): boolean {
return this.root.next === this.root
}
}
if (require.main === module) {
const nums = new LinkedList([1, 2, 3, 4, 5])
assert.strictEqual(nums.shift(), 1)
for (const num of nums) console.log(num)
console.log(`${nums}`)
}
export { LinkedList }
// java查找链表元素:起点折半查找 这样最坏情况也只要找一半就可以了。
// Node<E> node(int index) {
// assert isElementIndex(index);
// if (index < (size >> 1)) {
// Node<E> x = first;
// for (int i = 0; i < index; i++)
// x = x.next;
// return x;
// } else {
// Node<E> x = last;
// for (int i = size - 1; i > index; i--)
// x = x.prev;
// return x;
// }
// }