gxc-js-data-structure
Version:
Use JavaScript to implement some data structures and algorithms
246 lines (241 loc) • 6.4 kB
JavaScript
class Stack {
_items;
constructor(items = []) {
Object.defineProperty(this, "_items", {
enumerable: false,
configurable: false,
writable: false,
value: items,
});
}
get [Symbol.toStringTag]() {
return "Stack";
}
//添加一个新元素到栈顶
push(element) {
this._items.unshift(element);
return this._items;
}
//移除栈顶元素
pop() {
return this._items.shift();
}
//返回栈顶元素
peek() {
return this._items[0];
}
//如果栈里没有任何元素就返回true,否则返回false
isEmpty() {
return this._items.length === 0;
}
//返回栈里元素个数,类似数组的length
get size() {
return this._items.length;
}
//将栈结构的内容以字符串的形式返回
toString() {
return this._items.toString();
}
}
class Queue {
_items;
constructor(items = []) {
Object.defineProperty(this, "_items", {
enumerable: false,
configurable: false,
writable: false,
value: items,
});
}
get [Symbol.toStringTag]() {
return "Queue";
}
// 向队列尾部添加一个或多个新的项
enqueue(...args) {
this._items.push(...args);
}
// 移除队列的第一个项(最前面),并返回被移除的元素
dequeue() {
return this._items.shift();
}
// 返回队列中第一个元素——最先被添加的项,不改变队列,,类似栈的peek
front() {
return this._items[0];
}
// 如果队列中不包含任何元素,返回true
isEmpty() {
return this._items.length === 0;
}
// 返回队列元素个数
get size() {
return this._items.length;
}
// 将队列中的内容转成字符串形式
toString() {
return this._items.join(" ");
}
}
class NodeItem {
data;
next;
constructor(data) {
this.data = data;
this.next = null;
}
get [Symbol.toStringTag]() {
return "NodeItem";
}
}
class LinkedList {
head;
constructor() {
this.head = null;
}
get [Symbol.toStringTag]() {
return "LinkedList";
}
/**
* 获取链表节点个数
*/
get size() {
let count = 0;
let current = this.head;
if (this.head === null)
return 0;
while (current) {
count++;
current = current.next;
}
return count;
}
/**
* 判断是否为空链表
*/
get isEmpty() {
return this.size === 0;
}
/**
* 指定位置插入节点
* @param item 节点
* @param index 节点位置
*/
insert(item, index = this.size) {
this.judgedIndex(index);
const nodeItem = new NodeItem(item);
if (index === 0) {
const next = this.head?.next || null;
this.head = nodeItem;
nodeItem.next = next;
}
else {
let prev = this.getPreviousItem(index);
nodeItem.next = prev.next?.next || null;
prev.next = nodeItem;
}
}
/**
* 更新指定位置的节点
* @param item 节点
* @param index 节点位置
*/
update(item, index) {
const nodeItem = this.findNodeItem(index);
if (nodeItem) {
nodeItem.data = item;
return nodeItem.data;
}
else {
throw new Error("update failed, there is no node at this location ");
}
}
/**
* 获取指定位置的节点数据
* @param index 节点位置
*/
find(index) {
const nodeItem = this.findNodeItem(index);
return nodeItem?.data;
}
/**
* 删除指定位置的节点
* @param index 节点位置
*/
removeAt(index) {
this.judgedIndex(index);
const nodeItem = this.findNodeItem(index);
if (nodeItem) {
if (index === 0) {
this.head = nodeItem.next;
return nodeItem.data;
}
const prevItem = this.getPreviousItem(index);
prevItem.next = nodeItem.next;
}
}
/**
* 删除链表中满足提供的测试函数的第一个节点
* @param fn
*/
remove(fn) {
let currentNode = this.head;
let currentIndex = 0;
while (currentNode) {
if (fn(currentNode)) {
const prevNode = this.getPreviousItem(currentIndex);
prevNode.next = currentNode.next;
return currentNode.data;
}
currentIndex++;
currentNode = currentNode.next;
}
}
/**
* 获取指定位置的节点
* @param index 节点位置
*/
findNodeItem(index) {
let currentIndex = 0;
let current = this.head;
while (current) {
if (currentIndex === index) {
return current;
}
current = current.next;
currentIndex++;
}
}
/**
* 判断输入的index是否合法
* @param index 索引
*/
judgedIndex(index) {
if (index < 0 || index > this.size) {
throw new Error(`index must be a non-negative number no greater than length! at judgedIndex(${index})`);
}
}
/**
* 获得当前位置前一个节点(index不为0)
* @param index 索引
*/
getPreviousItem(index) {
if (index === 0)
throw new Error("The first node has no previous node at getPreviousItem");
let current = this.head;
let currentIndex = 0;
while (current) {
if (currentIndex === index - 1) {
break;
}
current = current.next;
currentIndex++;
}
return current;
}
}
class DoubleLinkedList {
head;
constructor() {
this.head = null;
}
}
export { DoubleLinkedList, LinkedList, Queue, Stack };