UNPKG

gxc-js-data-structure

Version:

Use JavaScript to implement some data structures and algorithms

259 lines (251 loc) 7.38 kB
(function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'], factory) : (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.dataStructures = {})); })(this, (function (exports) { 'use strict'; 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; } } exports.DoubleLinkedList = DoubleLinkedList; exports.LinkedList = LinkedList; exports.Queue = Queue; exports.Stack = Stack; Object.defineProperty(exports, '__esModule', { value: true }); }));