Skip to content

Instantly share code, notes, and snippets.

@uhop
Last active July 27, 2024 19:30
Show Gist options
  • Save uhop/6c91ba63e81bf5110d7d00070bc9a33b to your computer and use it in GitHub Desktop.
Save uhop/6c91ba63e81bf5110d7d00070bc9a33b to your computer and use it in GitHub Desktop.
Minimal circular SLL and DLL (lists).
// doubly linked list
const removeNode = node => {
node.prev.next = node.next;
node.next.prev = node.prev;
node.prev = node.next = node;
return node;
};
class DLL {
constructor() {
this.prev = this.next = this;
}
isEmpty() {
return this.next === this;
}
pushFront(value) {
const node = {next: this.next, prev: this, value};
node.next.prev = node.prev.next = node;
return this;
}
pushBack(value) {
const node = {next: this, prev: this.prev, value};
node.next.prev = node.prev.next = node;
return this;
}
popFront() {
if (this.next === this) return; // undefined
return removeNode(this.next).value;
}
popBack() {
if (this.prev === this) return; // undefined
return removeNode(this.prev).value;
}
reverse() {
let node = this;
do {
const next = node.next;
[node.next, node.prev] = [node.prev, node.next];
node = next;
} while (node !== this);
return this;
}
clear() {
this.prev = this.next = this;
}
[Symbol.iterator]() {
const head = this;
let node = this.next;
return {
next() {
if (node === head) return {done: true};
const value = node.value;
node = node.next;
return {done: false, value};
}
};
}
getReverseIterator() {
const head = this;
return {
[Symbol.iterator]() {
let node = head.prev;
return {
next() {
if (node === head) return {done: true};
const value = node.value;
node = node.prev;
return {done: false, value};
}
};
}
};
}
}
export default DLL;
// singly linked list
class SLL {
constructor() {
this.tail = this.next = this;
}
isEmpty() {
return this.next === this;
}
pushFront(value) {
const node = {next: this.next, value};
this.next = node;
if (this.tail === this) this.tail = node;
return this;
}
pushBack(value) {
const node = {next: this.tail.next, value};
this.tail.next = node;
this.tail = node;
if (this.next === this) this.next = node;
return this;
}
popFront() {
if (this.next === this) return; // undefined
const node = this.next;
this.next = node.next;
if (this.next === this) this.tail = this;
return node.value;
}
reverse() {
for (let prev = this, node = prev.next; node !== this; ) {
const next = node.next;
node.next = prev;
prev = node;
node = next;
}
[this.next, this.tail] = [this.tail, this.next];
return this;
}
clear () {
this.tail = this.next = this;
}
[Symbol.iterator]() {
const head = this;
let node = this.next;
return {
next() {
if (node === head) return {done: true};
const value = node.value;
node = node.next;
return {done: false, value};
}
};
}
}
export default SLL;
import DLL from './dll.js';
const isEqual = (a, b) => {
if (a === b) return true;
if (a.length !== b.length) return false;
for (let i = 0; i < a.length; ++i) {
if (a[i] !== b[i]) return false;
}
return true;
};
const getRandomArray = (size, min = 0, max = 100) => {
const samples = new Array(size), magnitude = max - min;
for (let i = 0; i < samples.length; ++i) {
samples[i] = Math.floor(magnitude * Math.random()) + min;
}
return samples;
};
const list = new DLL(), samples = getRandomArray(100);
for (const sample of samples) {
list.pushFront(sample);
}
console.log({equal: isEqual([...list.getReverseIterator()], samples)});
list.reverse();
console.log({equal: isEqual([...list], samples)});
list.clear();
for (const sample of samples) {
list.pushBack(sample);
}
console.log({equal: isEqual([...list], samples)});
import SLL from './sll.js';
const isEqual = (a, b) => {
if (a === b) return true;
if (a.length !== b.length) return false;
for (let i = 0; i < a.length; ++i) {
if (a[i] !== b[i]) return false;
}
return true;
};
const getRandomArray = (size, min = 0, max = 100) => {
const samples = new Array(size), magnitude = max - min;
for (let i = 0; i < samples.length; ++i) {
samples[i] = Math.floor(magnitude * Math.random()) + min;
}
return samples;
};
const list = new SLL(), samples = getRandomArray(100);
for (const sample of samples) {
list.pushFront(sample);
}
list.reverse();
console.log({equal: isEqual([...list], samples)});
list.clear();
for (const sample of samples) {
list.pushBack(sample);
}
console.log({equal: isEqual([...list], samples)});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment