@nebulaaa/linked-list 1.0.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,78 @@
1
+ # @linked-list
2
+
3
+ 高性能泛型链表实现,包含单向链表 (`LinkedList`) 和双向链表 (`DoublyLinkedList`)。
4
+
5
+ ## 特性
6
+ - **泛型支持**:支持任意类型 `T`。
7
+ - **遍历安全**:`Each` 遍历在回调中执行 `Push` 或 `Remove` 时表现稳定,不会导致死循环或指针丢失。
8
+ - **双向校验**:双向链表提供可选的归属校验机制,确保操作的节点确实属于当前链表。
9
+ - **内存友好**:出链节点指针会被显式清空,优化 GC 效率。
10
+
11
+ ---
12
+
13
+ ## 1. LinkedList (单向链表)
14
+
15
+ 基础的单向链表,适用于简单的队列或栈场景。
16
+
17
+ ### 公共接口
18
+ | 方法 | 描述 | 时间复杂度 |
19
+ | :--- | :--- | :--- |
20
+ | `Push(value: T): this` | 在链表尾部追加节点 | $O(1)$ |
21
+ | `Unshift(value: T): this` | 在链表头部插入节点 | $O(1)$ |
22
+ | `Shift(): T \| undefined` | 移除并返回头节点的值 | $O(1)$ |
23
+ | `Pop(): T \| undefined` | 移除并返回尾节点的值 | $O(n)$ |
24
+ | `Find(predicate): Node \| null` | 根据条件查找第一个匹配节点 | $O(n)$ |
25
+ | `Remove(predicate): boolean` | 删除第一个匹配条件的节点 | $O(n)$ |
26
+ | `Each(callback): void` | 遍历所有节点 | $O(n)$ |
27
+ | `ToArray(): T[]` | 将链表转换为普通数组 | $O(n)$ |
28
+ | `Size: number` | 获取当前链表长度 (Getter) | $O(1)$ |
29
+ | `IsEmpty: boolean` | 判断链表是否为空 (Getter) | $O(1)$ |
30
+
31
+ ---
32
+
33
+ ## 2. DoublyLinkedList (双向链表)
34
+
35
+ 支持双向遍历和高效尾部操作的链表,适用于需要频繁在两端或中间插入/删除的场景。
36
+
37
+ ### 公共接口
38
+ | 方法 | 描述 | 时间复杂度 |
39
+ | :--- | :--- | :--- |
40
+ | `Push(value: T): this` | 在尾部追加节点 | $O(1)$ |
41
+ | `Unshift(value: T): this` | 在头部插入节点 | $O(1)$ |
42
+ | `Pop(): T \| undefined` | 移除并返回尾部节点的值 | $O(1)$ |
43
+ | `Shift(): T \| undefined` | 移除并返回头部节点的值 | $O(1)$ |
44
+ | `InsertAfter(node, value): Node \| null` | 在指定节点后插入 | $O(1)$ / $O(n)^*$ |
45
+ | `InsertBefore(node, value): Node \| null` | 在指定节点前插入 | $O(1)$ / $O(n)^*$ |
46
+ | `Remove(node): boolean` | 删除指定节点 | $O(1)$ / $O(n)^*$ |
47
+ | `Find(predicate): Node \| null` | 根据条件查找第一个匹配节点 | $O(n)$ |
48
+ | `Each(callback): void` | 遍历所有节点 | $O(n)$ |
49
+ | `ToArray(): T[]` | 将链表转换为普通数组 | $O(n)$ |
50
+ | `First: Node \| null` | 获取头节点 (Getter) | $O(1)$ |
51
+ | `Last: Node \| null` | 获取尾节点 (Getter) | $O(1)$ |
52
+ | `Size: number` | 获取当前链表长度 (Getter) | $O(1)$ |
53
+ | `IsEmpty: boolean` | 判断链表是否为空 (Getter) | $O(1)$ |
54
+
55
+ ### 归属校验 (`CheckOwnership`)
56
+ 双向链表引入了 `CheckOwnership` 标志位,用于控制是否在 `Remove` 和 `Insert` 操作时校验节点归属:
57
+ - **`CheckOwnership = false` (默认)**: 追求极致性能,直接操作指针。复杂度 $O(1)$。
58
+ - **`CheckOwnership = true`**: 增加安全性,防止误操作非本链表节点导致结构损坏。复杂度升至 $O(n)$。
59
+
60
+ ---
61
+
62
+ ## 示例
63
+
64
+ ```typescript
65
+ import { LinkedList, DoublyLinkedList } from '@linked-list';
66
+
67
+ // 单向链表
68
+ const list = new LinkedList<number>();
69
+ list.Push(1).Push(2).Unshift(0); // [0, 1, 2]
70
+ list.Each((v, i) => console.log(i, v));
71
+
72
+ // 双向链表
73
+ const dlist = new DoublyLinkedList<string>();
74
+ dlist.Push('A').Push('B');
75
+ dlist.CheckOwnership = true; // 开启安全检查
76
+ const node = dlist.First;
77
+ dlist.InsertAfter(node!, 'Mid'); // [A, Mid, B]
78
+ ```
@@ -196,6 +196,8 @@ class DoublyLinkedList {
196
196
  this._head = null;
197
197
  this._tail = null;
198
198
  this._size = 0;
199
+ /** 是否开启归属校验(防止误删/误插非本链表节点,开启后相关操作复杂度由 O(1) 变为 O(n)) */
200
+ this.CheckOwnership = false;
199
201
  }
200
202
  /** 链表当前长度 */
201
203
  get Size() {
@@ -284,7 +286,7 @@ class DoublyLinkedList {
284
286
  * @tip 节点须属于本链表且未被移除,否则返回 null 且链表不受影响
285
287
  */
286
288
  InsertAfter(node, value) {
287
- if (!this.owns(node))
289
+ if (this.CheckOwnership && !this.owns(node))
288
290
  return null;
289
291
  const newNode = new DoublyLinkedListNode(value);
290
292
  newNode.Prev = node;
@@ -305,7 +307,7 @@ class DoublyLinkedList {
305
307
  * @tip 节点须属于本链表且未被移除,否则返回 null 且链表不受影响
306
308
  */
307
309
  InsertBefore(node, value) {
308
- if (!this.owns(node))
310
+ if (this.CheckOwnership && !this.owns(node))
309
311
  return null;
310
312
  const newNode = new DoublyLinkedListNode(value);
311
313
  newNode.Next = node;
@@ -337,7 +339,7 @@ class DoublyLinkedList {
337
339
  */
338
340
  Remove(node) {
339
341
  // 归属校验:拦截来自其他链表或已被移除的节点,避免静默改写指针、错记 size
340
- if (!node || !this.owns(node))
342
+ if (!node || (this.CheckOwnership && !this.owns(node)))
341
343
  return false;
342
344
  if (node.Prev) {
343
345
  node.Prev.Next = node.Next;
@@ -81,6 +81,8 @@ declare class DoublyLinkedList<T> {
81
81
  private _head;
82
82
  private _tail;
83
83
  private _size;
84
+ /** 是否开启归属校验(防止误删/误插非本链表节点,开启后相关操作复杂度由 O(1) 变为 O(n)) */
85
+ CheckOwnership: boolean;
84
86
  /** 链表当前长度 */
85
87
  get Size(): number;
86
88
  /** 链表是否为空 */
@@ -1 +1 @@
1
- "use strict";class t{constructor(t){this.Next=null,this.Value=t}}class e{constructor(t){this.Prev=null,this.Next=null,this.Value=t}}exports.DoublyLinkedList=class{constructor(){this._head=null,this._tail=null,this._size=0}get Size(){return this._size}get IsEmpty(){return 0===this._size}get First(){return this._head}get Last(){return this._tail}Push(t){const i=new e(t);return this._tail?(i.Prev=this._tail,this._tail.Next=i,this._tail=i):this._head=this._tail=i,this._size++,this}Unshift(t){const i=new e(t);return this._head?(i.Next=this._head,this._head.Prev=i,this._head=i):this._head=this._tail=i,this._size++,this}Shift(){if(!this._head)return;const t=this._head.Value;if(this._head===this._tail)this._head=this._tail=null;else{const t=this._head.Next;this._head.Next=null,t.Prev=null,this._head=t}return this._size--,t}Pop(){if(!this._tail)return;const t=this._tail.Value;if(this._head===this._tail)this._head=this._tail=null;else{const t=this._tail.Prev;this._tail.Prev=null,t.Next=null,this._tail=t}return this._size--,t}InsertAfter(t,i){if(!this.owns(t))return null;const s=new e(i);return s.Prev=t,s.Next=t.Next,t.Next?t.Next.Prev=s:this._tail=s,t.Next=s,this._size++,s}InsertBefore(t,i){if(!this.owns(t))return null;const s=new e(i);return s.Next=t,s.Prev=t.Prev,t.Prev?t.Prev.Next=s:this._head=s,t.Prev=s,this._size++,s}owns(t){let e=this._head;for(;e;){if(e===t)return!0;e=e.Next}return!1}Remove(t){return!(!t||!this.owns(t))&&(t.Prev?t.Prev.Next=t.Next:this._head=t.Next,t.Next?t.Next.Prev=t.Prev:this._tail=t.Prev,t.Prev=null,t.Next=null,this._size--,!0)}Find(t){let e=this._head,i=0;for(;e;){if(t(e.Value,i))return e;e=e.Next,i++}return null}Each(t){const e=this._tail;let i=this._head,s=0;for(;i;){const h=i.Next;if(t(i.Value,s),i===e)break;i=h,s++}}ToArray(){const t=[];return this.Each(e=>t.push(e)),t}toString(){return this.ToArray().join(" <-> ")}},exports.DoublyLinkedListNode=e,exports.LinkedList=class{constructor(){this._head=null,this._tail=null,this._size=0}get Size(){return this._size}get IsEmpty(){return 0===this._size}Push(e){const i=new t(e);return this._head?(this._tail.Next=i,this._tail=i):this._head=this._tail=i,this._size++,this}Unshift(e){const i=new t(e);return this._head?(i.Next=this._head,this._head=i):this._head=this._tail=i,this._size++,this}Shift(){if(!this._head)return;const t=this._head.Value;return this._head=this._head.Next,this._head||(this._tail=null),this._size--,t}Pop(){if(!this._head)return;if(this._head===this._tail){const t=this._head.Value;return this._head=this._tail=null,this._size=0,t}let t=this._head;for(;t.Next&&t.Next!==this._tail;)t=t.Next;const e=this._tail.Value;return t.Next=null,this._tail=t,this._size--,e}Find(t){let e=this._head,i=0;for(;e;){if(t(e.Value,i))return e;e=e.Next,i++}return null}Remove(t){if(!this._head)return!1;if(t(this._head.Value,0))return this.Shift(),!0;let e=this._head,i=this._head.Next,s=1;for(;i;){if(t(i.Value,s))return e.Next=i.Next,i===this._tail&&(this._tail=e),this._size--,!0;e=i,i=i.Next,s++}return!1}Each(t){const e=this._tail;let i=this._head,s=0;for(;i;){const h=i.Next;if(t(i.Value,s),i===e)break;i=h,s++}}ToArray(){const t=[];return this.Each(e=>t.push(e)),t}toString(){return this.ToArray().join(" -> ")}},exports.LinkedListNode=t;
1
+ "use strict";class t{constructor(t){this.Next=null,this.Value=t}}class e{constructor(t){this.Prev=null,this.Next=null,this.Value=t}}exports.DoublyLinkedList=class{constructor(){this._head=null,this._tail=null,this._size=0,this.CheckOwnership=!1}get Size(){return this._size}get IsEmpty(){return 0===this._size}get First(){return this._head}get Last(){return this._tail}Push(t){const i=new e(t);return this._tail?(i.Prev=this._tail,this._tail.Next=i,this._tail=i):this._head=this._tail=i,this._size++,this}Unshift(t){const i=new e(t);return this._head?(i.Next=this._head,this._head.Prev=i,this._head=i):this._head=this._tail=i,this._size++,this}Shift(){if(!this._head)return;const t=this._head.Value;if(this._head===this._tail)this._head=this._tail=null;else{const t=this._head.Next;this._head.Next=null,t.Prev=null,this._head=t}return this._size--,t}Pop(){if(!this._tail)return;const t=this._tail.Value;if(this._head===this._tail)this._head=this._tail=null;else{const t=this._tail.Prev;this._tail.Prev=null,t.Next=null,this._tail=t}return this._size--,t}InsertAfter(t,i){if(this.CheckOwnership&&!this.owns(t))return null;const s=new e(i);return s.Prev=t,s.Next=t.Next,t.Next?t.Next.Prev=s:this._tail=s,t.Next=s,this._size++,s}InsertBefore(t,i){if(this.CheckOwnership&&!this.owns(t))return null;const s=new e(i);return s.Next=t,s.Prev=t.Prev,t.Prev?t.Prev.Next=s:this._head=s,t.Prev=s,this._size++,s}owns(t){let e=this._head;for(;e;){if(e===t)return!0;e=e.Next}return!1}Remove(t){return!(!t||this.CheckOwnership&&!this.owns(t))&&(t.Prev?t.Prev.Next=t.Next:this._head=t.Next,t.Next?t.Next.Prev=t.Prev:this._tail=t.Prev,t.Prev=null,t.Next=null,this._size--,!0)}Find(t){let e=this._head,i=0;for(;e;){if(t(e.Value,i))return e;e=e.Next,i++}return null}Each(t){const e=this._tail;let i=this._head,s=0;for(;i;){const h=i.Next;if(t(i.Value,s),i===e)break;i=h,s++}}ToArray(){const t=[];return this.Each(e=>t.push(e)),t}toString(){return this.ToArray().join(" <-> ")}},exports.DoublyLinkedListNode=e,exports.LinkedList=class{constructor(){this._head=null,this._tail=null,this._size=0}get Size(){return this._size}get IsEmpty(){return 0===this._size}Push(e){const i=new t(e);return this._head?(this._tail.Next=i,this._tail=i):this._head=this._tail=i,this._size++,this}Unshift(e){const i=new t(e);return this._head?(i.Next=this._head,this._head=i):this._head=this._tail=i,this._size++,this}Shift(){if(!this._head)return;const t=this._head.Value;return this._head=this._head.Next,this._head||(this._tail=null),this._size--,t}Pop(){if(!this._head)return;if(this._head===this._tail){const t=this._head.Value;return this._head=this._tail=null,this._size=0,t}let t=this._head;for(;t.Next&&t.Next!==this._tail;)t=t.Next;const e=this._tail.Value;return t.Next=null,this._tail=t,this._size--,e}Find(t){let e=this._head,i=0;for(;e;){if(t(e.Value,i))return e;e=e.Next,i++}return null}Remove(t){if(!this._head)return!1;if(t(this._head.Value,0))return this.Shift(),!0;let e=this._head,i=this._head.Next,s=1;for(;i;){if(t(i.Value,s))return e.Next=i.Next,i===this._tail&&(this._tail=e),this._size--,!0;e=i,i=i.Next,s++}return!1}Each(t){const e=this._tail;let i=this._head,s=0;for(;i;){const h=i.Next;if(t(i.Value,s),i===e)break;i=h,s++}}ToArray(){const t=[];return this.Each(e=>t.push(e)),t}toString(){return this.ToArray().join(" -> ")}},exports.LinkedListNode=t;
@@ -1 +1 @@
1
- class t{constructor(t){this.Next=null,this.Value=t}}class e{constructor(){this._head=null,this._tail=null,this._size=0}get Size(){return this._size}get IsEmpty(){return 0===this._size}Push(e){const i=new t(e);return this._head?(this._tail.Next=i,this._tail=i):this._head=this._tail=i,this._size++,this}Unshift(e){const i=new t(e);return this._head?(i.Next=this._head,this._head=i):this._head=this._tail=i,this._size++,this}Shift(){if(!this._head)return;const t=this._head.Value;return this._head=this._head.Next,this._head||(this._tail=null),this._size--,t}Pop(){if(!this._head)return;if(this._head===this._tail){const t=this._head.Value;return this._head=this._tail=null,this._size=0,t}let t=this._head;for(;t.Next&&t.Next!==this._tail;)t=t.Next;const e=this._tail.Value;return t.Next=null,this._tail=t,this._size--,e}Find(t){let e=this._head,i=0;for(;e;){if(t(e.Value,i))return e;e=e.Next,i++}return null}Remove(t){if(!this._head)return!1;if(t(this._head.Value,0))return this.Shift(),!0;let e=this._head,i=this._head.Next,s=1;for(;i;){if(t(i.Value,s))return e.Next=i.Next,i===this._tail&&(this._tail=e),this._size--,!0;e=i,i=i.Next,s++}return!1}Each(t){const e=this._tail;let i=this._head,s=0;for(;i;){const h=i.Next;if(t(i.Value,s),i===e)break;i=h,s++}}ToArray(){const t=[];return this.Each(e=>t.push(e)),t}toString(){return this.ToArray().join(" -> ")}}class i{constructor(t){this.Prev=null,this.Next=null,this.Value=t}}class s{constructor(){this._head=null,this._tail=null,this._size=0}get Size(){return this._size}get IsEmpty(){return 0===this._size}get First(){return this._head}get Last(){return this._tail}Push(t){const e=new i(t);return this._tail?(e.Prev=this._tail,this._tail.Next=e,this._tail=e):this._head=this._tail=e,this._size++,this}Unshift(t){const e=new i(t);return this._head?(e.Next=this._head,this._head.Prev=e,this._head=e):this._head=this._tail=e,this._size++,this}Shift(){if(!this._head)return;const t=this._head.Value;if(this._head===this._tail)this._head=this._tail=null;else{const t=this._head.Next;this._head.Next=null,t.Prev=null,this._head=t}return this._size--,t}Pop(){if(!this._tail)return;const t=this._tail.Value;if(this._head===this._tail)this._head=this._tail=null;else{const t=this._tail.Prev;this._tail.Prev=null,t.Next=null,this._tail=t}return this._size--,t}InsertAfter(t,e){if(!this.owns(t))return null;const s=new i(e);return s.Prev=t,s.Next=t.Next,t.Next?t.Next.Prev=s:this._tail=s,t.Next=s,this._size++,s}InsertBefore(t,e){if(!this.owns(t))return null;const s=new i(e);return s.Next=t,s.Prev=t.Prev,t.Prev?t.Prev.Next=s:this._head=s,t.Prev=s,this._size++,s}owns(t){let e=this._head;for(;e;){if(e===t)return!0;e=e.Next}return!1}Remove(t){return!(!t||!this.owns(t))&&(t.Prev?t.Prev.Next=t.Next:this._head=t.Next,t.Next?t.Next.Prev=t.Prev:this._tail=t.Prev,t.Prev=null,t.Next=null,this._size--,!0)}Find(t){let e=this._head,i=0;for(;e;){if(t(e.Value,i))return e;e=e.Next,i++}return null}Each(t){const e=this._tail;let i=this._head,s=0;for(;i;){const h=i.Next;if(t(i.Value,s),i===e)break;i=h,s++}}ToArray(){const t=[];return this.Each(e=>t.push(e)),t}toString(){return this.ToArray().join(" <-> ")}}export{s as DoublyLinkedList,i as DoublyLinkedListNode,e as LinkedList,t as LinkedListNode};
1
+ class t{constructor(t){this.Next=null,this.Value=t}}class e{constructor(){this._head=null,this._tail=null,this._size=0}get Size(){return this._size}get IsEmpty(){return 0===this._size}Push(e){const i=new t(e);return this._head?(this._tail.Next=i,this._tail=i):this._head=this._tail=i,this._size++,this}Unshift(e){const i=new t(e);return this._head?(i.Next=this._head,this._head=i):this._head=this._tail=i,this._size++,this}Shift(){if(!this._head)return;const t=this._head.Value;return this._head=this._head.Next,this._head||(this._tail=null),this._size--,t}Pop(){if(!this._head)return;if(this._head===this._tail){const t=this._head.Value;return this._head=this._tail=null,this._size=0,t}let t=this._head;for(;t.Next&&t.Next!==this._tail;)t=t.Next;const e=this._tail.Value;return t.Next=null,this._tail=t,this._size--,e}Find(t){let e=this._head,i=0;for(;e;){if(t(e.Value,i))return e;e=e.Next,i++}return null}Remove(t){if(!this._head)return!1;if(t(this._head.Value,0))return this.Shift(),!0;let e=this._head,i=this._head.Next,s=1;for(;i;){if(t(i.Value,s))return e.Next=i.Next,i===this._tail&&(this._tail=e),this._size--,!0;e=i,i=i.Next,s++}return!1}Each(t){const e=this._tail;let i=this._head,s=0;for(;i;){const h=i.Next;if(t(i.Value,s),i===e)break;i=h,s++}}ToArray(){const t=[];return this.Each(e=>t.push(e)),t}toString(){return this.ToArray().join(" -> ")}}class i{constructor(t){this.Prev=null,this.Next=null,this.Value=t}}class s{constructor(){this._head=null,this._tail=null,this._size=0,this.CheckOwnership=!1}get Size(){return this._size}get IsEmpty(){return 0===this._size}get First(){return this._head}get Last(){return this._tail}Push(t){const e=new i(t);return this._tail?(e.Prev=this._tail,this._tail.Next=e,this._tail=e):this._head=this._tail=e,this._size++,this}Unshift(t){const e=new i(t);return this._head?(e.Next=this._head,this._head.Prev=e,this._head=e):this._head=this._tail=e,this._size++,this}Shift(){if(!this._head)return;const t=this._head.Value;if(this._head===this._tail)this._head=this._tail=null;else{const t=this._head.Next;this._head.Next=null,t.Prev=null,this._head=t}return this._size--,t}Pop(){if(!this._tail)return;const t=this._tail.Value;if(this._head===this._tail)this._head=this._tail=null;else{const t=this._tail.Prev;this._tail.Prev=null,t.Next=null,this._tail=t}return this._size--,t}InsertAfter(t,e){if(this.CheckOwnership&&!this.owns(t))return null;const s=new i(e);return s.Prev=t,s.Next=t.Next,t.Next?t.Next.Prev=s:this._tail=s,t.Next=s,this._size++,s}InsertBefore(t,e){if(this.CheckOwnership&&!this.owns(t))return null;const s=new i(e);return s.Next=t,s.Prev=t.Prev,t.Prev?t.Prev.Next=s:this._head=s,t.Prev=s,this._size++,s}owns(t){let e=this._head;for(;e;){if(e===t)return!0;e=e.Next}return!1}Remove(t){return!(!t||this.CheckOwnership&&!this.owns(t))&&(t.Prev?t.Prev.Next=t.Next:this._head=t.Next,t.Next?t.Next.Prev=t.Prev:this._tail=t.Prev,t.Prev=null,t.Next=null,this._size--,!0)}Find(t){let e=this._head,i=0;for(;e;){if(t(e.Value,i))return e;e=e.Next,i++}return null}Each(t){const e=this._tail;let i=this._head,s=0;for(;i;){const h=i.Next;if(t(i.Value,s),i===e)break;i=h,s++}}ToArray(){const t=[];return this.Each(e=>t.push(e)),t}toString(){return this.ToArray().join(" <-> ")}}export{s as DoublyLinkedList,i as DoublyLinkedListNode,e as LinkedList,t as LinkedListNode};
@@ -194,6 +194,8 @@ class DoublyLinkedList {
194
194
  this._head = null;
195
195
  this._tail = null;
196
196
  this._size = 0;
197
+ /** 是否开启归属校验(防止误删/误插非本链表节点,开启后相关操作复杂度由 O(1) 变为 O(n)) */
198
+ this.CheckOwnership = false;
197
199
  }
198
200
  /** 链表当前长度 */
199
201
  get Size() {
@@ -282,7 +284,7 @@ class DoublyLinkedList {
282
284
  * @tip 节点须属于本链表且未被移除,否则返回 null 且链表不受影响
283
285
  */
284
286
  InsertAfter(node, value) {
285
- if (!this.owns(node))
287
+ if (this.CheckOwnership && !this.owns(node))
286
288
  return null;
287
289
  const newNode = new DoublyLinkedListNode(value);
288
290
  newNode.Prev = node;
@@ -303,7 +305,7 @@ class DoublyLinkedList {
303
305
  * @tip 节点须属于本链表且未被移除,否则返回 null 且链表不受影响
304
306
  */
305
307
  InsertBefore(node, value) {
306
- if (!this.owns(node))
308
+ if (this.CheckOwnership && !this.owns(node))
307
309
  return null;
308
310
  const newNode = new DoublyLinkedListNode(value);
309
311
  newNode.Next = node;
@@ -335,7 +337,7 @@ class DoublyLinkedList {
335
337
  */
336
338
  Remove(node) {
337
339
  // 归属校验:拦截来自其他链表或已被移除的节点,避免静默改写指针、错记 size
338
- if (!node || !this.owns(node))
340
+ if (!node || (this.CheckOwnership && !this.owns(node)))
339
341
  return false;
340
342
  if (node.Prev) {
341
343
  node.Prev.Next = node.Next;
package/dist/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nebulaaa/linked-list",
3
- "version": "1.0.0",
3
+ "version": "2.0.0",
4
4
  "description": "链表扩展包",
5
5
  "author": "doooreyn",
6
6
  "license": "MIT",
@@ -23,6 +23,7 @@
23
23
  "default": "./linked-list.cjs"
24
24
  },
25
25
  "./min": {
26
+ "types": "./linked-list.d.ts",
26
27
  "require": "./linked-list.min.cjs",
27
28
  "import": "./linked-list.min.mjs"
28
29
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nebulaaa/linked-list",
3
- "version": "1.0.0",
3
+ "version": "2.0.0",
4
4
  "description": "链表扩展包",
5
5
  "main": "./dist/linked-list.cjs",
6
6
  "module": "./dist/linked-list.mjs",