Skip to content

Commit

Permalink
feat: add linked list
Browse files Browse the repository at this point in the history
  • Loading branch information
ppeeou committed Mar 7, 2024
1 parent 22858e7 commit 2bbede9
Show file tree
Hide file tree
Showing 3 changed files with 101 additions and 45 deletions.
60 changes: 15 additions & 45 deletions src/Lazy/fork.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { isAsyncIterable, isIterable } from "../_internal/utils";
import { LinkedList } from "../dataStructure/linkedList/linkedList";
import type { LinkedListNode } from "../dataStructure/linkedList/linkedListNode";
import isNil from "../isNil";
import type IterableInfer from "../types/IterableInfer";

Expand All @@ -7,51 +9,22 @@ type ReturnForkType<A extends Iterable<unknown> | AsyncIterable<unknown>> =
? AsyncIterableIterator<IterableInfer<A>>
: IterableIterator<IterableInfer<A>>;

type Node<T> = { value: T; done?: boolean };
type Value = any;

class ForkItem<T> {
node: Node<T>;
nextNode: ForkItem<T> | null;

constructor(node: Node<T>) {
this.node = node;
this.nextNode = null;
}
}

class ForkQueue<T> {
head: ForkItem<T>;

current: ForkItem<T>;

constructor() {
this.head = new ForkItem(null as any);
this.current = this.head;
}

toString() {
const arr = [];
let cur: ForkItem<T> | null = this.head.nextNode;
while (cur) {
arr.push(cur.node.value);
cur = cur.nextNode;
}

return arr.join(", ");
}
}

const forkMap = new WeakMap<any, ForkQueue<any>>();
const forkMap = new WeakMap<
Iterator<Value>,
LinkedList<IteratorResult<Value>>
>();

function sync<T>(iterable: Iterable<T>) {
const iterator = iterable[Symbol.iterator]();
let queue = forkMap.get(iterator) as ForkQueue<any>;
let queue = forkMap.get(iterator) as LinkedList<IteratorResult<T>>;
if (!queue) {
queue = new ForkQueue();
queue = new LinkedList();
forkMap.set(iterator, queue);
}

let cur = queue.current;
let current: LinkedListNode<IteratorResult<T>> | null = queue.getTail();
let done = false;

return {
Expand All @@ -67,20 +40,17 @@ function sync<T>(iterable: Iterable<T>) {
};
}

const item = cur.nextNode;
const item = current?.getNext();
if (isNil(item)) {
const node = iterator.next();
cur.nextNode = new ForkItem(node);
cur = cur.nextNode;

queue.current = cur;
current = queue.insertLast(node);
done = node.done ?? true;

return cur.node;
return node;
}

cur = item;
return cur.node;
current = item;
return current.getValue();
},
};
}
Expand Down
59 changes: 59 additions & 0 deletions src/dataStructure/linkedList/linkedList.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { LinkedListNode } from "./linkedListNode";

export class LinkedList<T> {
private head: LinkedListNode<T>;
private tail: LinkedListNode<T>;

constructor() {
this.head = new LinkedListNode(null as unknown as T);
this.tail = this.head;
}

insertFirst(value: T): LinkedListNode<T> {
const node = new LinkedListNode(value);
if (this.isEmpty()) {
this.tail = node;
this.head.setNextNode(node);
} else {
node.setNextNode(this.head.getNext());
this.head.setNextNode(node);
}

return node;
}

insertLast(value: T): LinkedListNode<T> {
if (this.isEmpty()) {
return this.insertFirst(value);
}

const node = new LinkedListNode(value);
this.tail?.setNextNode(node);
this.tail = node;
return node;
}

isEmpty() {
return !this.head.hasNext();
}

getHead() {
return this.head;
}

getTail() {
return this.tail;
}

toArray() {
const arr = [];
let cur = this.head;
while (cur.hasNext()) {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
cur = cur.getNext()!;
arr.push(cur);
}

return arr;
}
}
27 changes: 27 additions & 0 deletions src/dataStructure/linkedList/linkedListNode.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
export class LinkedListNode<T> {
private value: T;
private next: LinkedListNode<T> | null;

constructor(value: T) {
this.value = value;
this.next = null;
}

setNextNode(node: LinkedListNode<T> | null) {
this.next = node;

return node;
}

getValue() {
return this.value;
}

getNext() {
return this.next;
}

hasNext() {
return this.next instanceof LinkedListNode;
}
}

0 comments on commit 2bbede9

Please sign in to comment.