数组
class MyArray {
constructor(capacity=10) {
this._data = new Array(capacity);
this._size = 0;
}
get length() {
return this._size;
}
get capacity() {
return this._data.length;
}
insert(index, e) {
if (index < 0 || index >= this._data.length) {
throw new RangeError("index is invalid");
}
for (let i=this._size-1; i>=index; i--) {
this._data[i+1] = this._data[i];
}
this._data[index] = e;
this._size++;
}
insertLast(e) {
this.insert(this._size, e);
}
insertFirst(e) {
this.insert(0, e);
}
get(index) {
if (index < 0 || index >= this._data.length) {
throw new RangeError("index is invalid");
}
return this._data[index];
}
remove(index) {
if (index < 0 || index >= this._data.length) {
throw new RangeError("index is invalid");
}
let ret = this._data[index];
for (let i=index,len=this._size-1; i<=len; i++) {
this._data[i] = this._data[i+1];
}
this._size--;
return ret;
}
set(index, e) {
if (index < 0 || index >= this._data.length) {
throw new RangeError("index is invalid");
}
if (this._data[index]) {
this._data[index] = e;
} else {
this.insertLast(e);
}
}
includes(e) {
for (let i=0,len=this._size; i<len; i++) {
if (Object.is(this._data[i], e)) {
return true;
}
}
return false;
}
find(e) {
for (let i=0,len=this._size; i<len; i++) {
if (Object.is(this._data[i], e)) {
return i;
}
}
return -1;
}
toString() {
let str = "[";
for (let i=0,len=this._size; i<len; i++) {
str += this._data[i];
if (i != len-1) {
str += ",";
}
}
str += "]";
return str;
}
}
export default MyArray;
链表
class LinkedListNode {
constructor(e, next=null) {
this.e = e;
this.next = next;
}
}
class LinkedList {
constructor() {
this._dummyhead = new LinkedListNode(null);
this._tail = null;
this._size = 0;
}
get length() {
return this._size;
}
get isEmpty() {
return this._size == 0;
}
insert(index, e) {
if (index < 0 || index>this._size) {
throw new RangeError("index is invalid");
}
let cur = this._dummyhead;
for (let i=0; i<index; i++) {
cur = cur.next;
}
cur.next = new LinkedListNode(e, cur.next);
this._tail = cur.next;
this._size++;
}
insertFirst(e) {
this._dummyhead.next = new LinkedListNode(e, this._dummyhead.next);
if (this._size == 0) {
this._tail = this._dummyhead.next;
}
this._size++;
}
insertLast(e) {
if (this._size == 0) {
this._dummyhead.next = new LinkedListNode(e);
this._tail = this._dummyhead.next;
} else {
this._tail.next = new LinkedListNode(e);
this._tail = this._tail.next;
}
this._size++;
}
removeElement(e) {
if (this.isEmpty) {
return new Error("Element is empty");
}
let prev = this._dummyhead;
while (prev != null) {
if (Object.is(prev.next.e,e)) {
break;
}
prev = prev.next;
}
if (prev != null) {
let ret = prev.next;
prev.next = ret.next;
ret.next = null;
if (Object.is(ret.e, this._tail.e)) {
this._tail = prev;
}
this._size--;
return ret;
}
return null;
}
removeIndex(index) {
if (index < 0 || index>this._size) {
throw new RangeError("index is invalid");
}
if (this.isEmpty) {
return new Error("Element is empty");
}
let prev = this._dummyhead;
let ret;
for (let i=0; i<index; i++) {
prev = prev.next;
}
ret = prev.next;
prev.next = ret.next;
ret.next = null;
if (Object.is(ret.e, this._tail.e)) {
this._tail = prev;
}
this._size--;
return ret;
}
find(e) {
let cur = this._dummyhead.next;
let index = 0;
while (cur !== null) {
if (Object.is(cur.e, e)) {
break;
}
index++;
cur = cur.next;
}
if (cur == null) {
return -1;
} else {
return index;
}
}
contains(e) {
let result = this.find(e);
return result != -1 ? true : false;
}
get(index) {
if (index < 0 || index>this._size) {
throw new RangeError("index is invalid");
}
let cur = this._dummyhead.next;
for (let i=0; i<index; i++) {
cur = cur.next;
}
return cur;
}
toString() {
let res = "";
let cur = this._dummyhead.next;
for (let i=0,len=this._size; i<len; i++) {
res += cur.e;
if (i != len-1) {
res += " > ";
}
cur = cur.next;
}
return res;
}
}
export default LinkedList;
栈
- 数组实现
class Stack {
constructor() {
this._data = [];
}
push(e) {
this._data.push(e);
}
pop() {
return this._data.pop();
}
peek() {
return this._data[0];
}
isEmpty() {
return this._data.length == 0;
}
get length() {
return this._data.length;
}
}
export default Stack;
- 链表实现
import LinkedList from "./LinkedList.js";
class Stack {
constructor() {
this._data = new LinkedList();
}
push(e) {
this._data.insertFirst(e);
}
pop() {
return this._data.removeIndex(0);
}
peek() {
return this._data.get(0);
}
get isEmpty() {
return this._data.isEmpty;
}
get lenght() {
return this._data.length;
}
}
export default Stack;
队列
- 数组实现
class Queue {
constructor() {
this._data = [];
}
enqueue(e) {
this._data.push(e);
}
dequeue() {
return this._data.shift();
}
front() {
return this._data[0];
}
get isEmpty() {
return this._data.length == 0;
}
get length() {
return this._data.length;
}
toString() {
return "Front ["+this._data.toString+"]";
}
}
export default Queue;
- 链表实现
import LinkedList from "./LinkedList.js";
class Queue {
constructor() {
this._data = new LinkedList();
}
enqueue(e) {
this._data.insertLast(e);
}
dequeue() {
return this._data.removeIndex(0);
}
front() {
return this._data.get(0);
}
get isEmpty() {
return this._data.length == 0;
}
get length() {
return this._data.length;
}
toString() {
return "Front "+this._data.toString();
}
}
export default Queue;
二分搜索树
import Queue from "./LinkedListQueue.js";
class Node {
constructor(e=null) {
this.e = e;
this.left = null;
this.right = null;
}
}
class BST {
constructor() {
this._root = null;
this._size = 0;
}
get size() {
return this._size;
}
get isEmpty() {
return this._size == 0;
}
insert(e) {
let _this = this;
if (this._root == null) {
this._root = new Node(e);
this._size++;
} else {
this._root = _insert(this._root);
}
function _insert(node) {
if (node == null) {
_this._size++;
return new Node(e);
}
if (e < node.e) {
node.left = _insert(node.left);
} else if (e > node.e) {
node.right = _insert(node.right);
}
return node;
}
}
maximum() {
if (this.isEmpty) {
throw new Error("data is empty");
}
return this._maximum(this._root);
}
_maximum(node) {
if (node.right == null) {
return node;
}
return this._maximum(node.right);
}
minimum() {
if (this.isEmpty) {
throw new Error("data is empty");
}
return this._minimum(this._root);
}
_minimum(node) {
if (node.left == null) {
return node;
}
return this._minimum(node.left);
}
removeMin() {
if (this.isEmpty) {
throw new Error("data is empty");
}
let minimum = this.minimum();
this._root = this._removeMin(this._root);
return minimum;
}
_removeMin(node) {
if (node.left == null) {
let rightNode = node.right;
node.right = null;
this._size--;
return rightNode;
}
node.left = this._removeMin(node.left);
return node;
}
removeMax() {
if (this.isEmpty) {
throw new Error("data is empty");
}
let maximum = this.maximum();
this._root = this._removeMax(this._root);
return maximum;
}
_removeMax(node) {
if (node.right == null) {
let leftNode = node.left;
node.left = null;
this._size--;
return leftNode;
}
node.right = this._removeMax(node.right);
return node;
}
remove(e) {
if (this.isEmpty) {
throw new Error("data is empty");
}
let _this = this;
this._root = _remove(this._root);
function _remove(node) {
if (node == null) {
return null;
}
if (e < node.e) {
node.left = _remove(node.left);
return node;
} else if (e > node.e) {
node.right = _remove(node.right);
return node;
} else {
if (node.left == null) {
let rightNode = node.right;
node.right = null;
_this._size--;
return rightNode;
} else if (node.right == null) {
let leftNode = node.left;
node.left = null;
_this._size--;
return leftNode;
}
let successor = _this._minimum(node.right);
successor.right = _this._removeMin(node.right);
successor.left = node.left;
return successor;
}
}
}
find(e) {
if (this.isEmpty) {
throw new Error("data is empty");
}
return _find(this._root);
function _find(node) {
if (node == null) {
return null;
}
if (e < node.e) {
node.left = _find(node.left);
return node.left;
} else if (e > node.e) {
node.right = _find(node.right);
return node.right;
} else {
return node;
}
}
}
preOrder() {
_preOrder(this._root);
function _preOrder(node) {
if (node == null) {
return;
}
console.log(node.e);
_preOrder(node.left);
_preOrder(node.right);
}
}
inOrder() {
_inOrder(this._root);
function _inOrder(node) {
if (node == null) {
return;
}
_inOrder(node.left);
console.log(node.e);
_inOrder(node.right);
}
}
postOrder() {
_postOrder(this._root);
function _postOrder(node) {
if (node == null) {
return;
}
_postOrder(node.left);
_postOrder(node.right);
console.log(node.e);
}
}
levelOrder() {
let queue = new Queue();
let node;
queue.enqueue(this._root);
while (!queue.isEmpty) {
node = queue.dequeue();
console.log(node.e.e);
if (node.e.left != null) {
queue.enqueue(node.e.left);
}
if (node.e.right != null) {
queue.enqueue(node.e.right);
}
}
}
contains(e) {
return _contains(this._root);
function _contains(node) {
if (node == null) {
return false;
}
if (e < node.e) {
node.left = _contains(node.left);
return node.left;
} else if (e > node.e) {
node.right = _contains(node.right);
return node.right;
} else {
return true;
}
}
}
}
export default BST;
集合
- 数组实现
class Set {
constructor() {
this._data = [];
}
contains(e) {
return this._data.includes(e);
}
add(e) {
if (!this.contains(e)) {
this._data.push(e);
}
}
remove(e) {
let index = this._data.indexOf(e);
this._data.splice(index,1);
return this._data[index];
}
get length() {
return this._data.length;
}
get isEmpty() {
return this.length == 0;
}
}
export default Set;
- 链表实现
import LinkedList from "./LinkedList.js";
class Set {
constructor() {
this._data = new LinkedList();
}
contains(e) {
return this._data.contains(e);
}
add(e) {
if (!this.contains(e)) {
this._data.insertFirst(e);
}
}
remove(e) {
return this._data.removeElement(e);
}
get length() {
return this._data.length;
}
get isEmpty() {
return this.length == 0;
}
}
export default Set;
映射
class Node {
constructor(key, value) {
this.key = key;
this.value = value;
this.next = null;
}
}
class Map {
constructor() {
this._root = null;
this._length = 0;
}
get length() {
return this._length;
}
get isEmpty() {
return this._length == 0;
}
add(key, value) {
if (this._root == null) {
this._root = new Node(key, value);
} else {
let node = new Node(key, value);
node.next = this._root;
this._root = node;
}
this._length++;
}
get(key) {
return _get(this._root);
function _get(node) {
if (node == null) {
return null;
}
if (Object.is(key, node.key)) {
return node.value;
} else {
return _get(node.next);
}
}
}
set(key, value) {
return _set(this._root);
function _set(node) {
if (node == null) {
return null;
}
if (Object.is(key, node.key)) {
node.value = value;
return node;
} else {
return _set(node.next);
}
}
}
remove(key) {
let _this = this;
let ret = this.get(key);
if (ret == null) {
return null;
}
if (Object.is(key, this._root.key)) {
let node = this._root;
this._root = this._root.next;
node.next = null;
this._length--;
} else {
this._root = _remove(this._root);
}
return ret;
function _remove(node) {
if (node.next == null) {
return null;
}
if (Object.is(key, node.next.key)) {
let removeNode = node.next;
node.next = node.next.next;
removeNode.next = null;
_this._length--;
return node;
} else {
return _remove(node.next);
}
}
}
}
export default Map;
最大堆
class MaxHeap {
constructor(arr=[]) {
this._data = arr;
for (let i=this._parent(arr.length-1); i>=0; i--) {
this._shiftDown(i);
}
}
get length() {
return this._data.length;
}
get isEmpty() {
return this._data.length == 0;
}
add(e) {
this._data.push(e);
this._shiftUp(this._data.length-1);
}
get() {
return this._data[0];
}
remove(e) {
let ret = this._data.shift();
this._shiftDown(0);
return ret;
}
_parent(index) {
if (index == 0) {
throw new RangeError("index-0 doesn't parent");
}
return Math.floor((index-1) / 2);
}
_leftChild(index) {
return index*2+1;
}
_rightChild(index) {
return index*2+2;
}
_shiftUp(k) {
let data = this._data;
while (k>0 && data[this._parent(k)] < data[k]) {
let parent = data[this._parent(k)];
data[this._parent(k)] = data[k];
data[k] = parent;
k=this._parent(k);
}
}
_shiftDown(k) {
let size = this._data.length;
while (this._leftChild(k) < size) {
let j = this._leftChild(k);
let data = this._data;
if (j+1 < size && data[j+1] > data[j]) {
j = this._rightChild(k);
}
if (data[k] > data[j]) {
break;
}
let agent = data[k];
data[k] = data[j];
data[j] = agent;
k=j;
}
}
}
export default MaxHeap;
优先队列
import MaxHeap from "./MaxHeap.js";
class PriorityQueue {
constructor() {
this._data = new MaxHeap();
}
get length() {
return this._data.length;
}
get isEmpty() {
return this._data.isEmpty;
}
enqueue(e) {
this._data.add(e);
}
dequeue() {
return this._data.remove();
}
front() {
return this._data.get();
}
}
export default PriorityQueue;
前缀树
class Node {
constructor(isWord=false) {
this.isWord = isWord;
this.next = {};
}
}
class Trie {
constructor() {
this._root = new Node();
this._size = 0;
}
get size() {
return this._size;
}
add(word) {
let cur = this._root;
for (let i=0; i<word.length; i++) {
let key = word.charAt(i);
if (cur.next[key] == undefined) {
cur.next[key] = new Node();
}
cur = cur.next[key];
}
if (!cur.isWord) {
cur.isWord = true;
this._size++;
}
}
contains(word) {
let cur = this._root;
for(let i=0; i<word.length; i++) {
let key = word.charAt(i);
if (cur.next[key] == undefined) {
return false;
}
cur = cur.next[key];
}
return cur.isWord;
}
isPrefix(prefix) {
let cur = this._root;
for(let i=0; i<prefix.length; i++) {
let key = prefix.charAt(i);
if (cur.next[key] == undefined) {
return false;
}
cur = cur.next[key];
}
return true;
}
}
export default Trie;
并查集
class UnionFind {
constructor(size) {
if (!size) {
throw new TypeError("size is empty");
}
this._parent = new Array(size);
this._rank = new Array(size);
for (let i=0; i<this._parent.length; i++) {
this._parent[i] = i;
this._rank[i] = 1;
}
}
get size() {
return this._parent.length;
}
_find(p) {
if (p<0 && p>=parent.length) {
throw new RangeError(`${p} is invalid`);
}
while (p != this._parent[p]) {
this._parent[p] = this._parent[this._parent[p]];
p = this._parent[p];
}
return p;
}
isConnected(p, q) {
return this._find(p) == this._find(q);
}
unionElement(p, q) {
let pRoot = this._find(p);
let qRoot = this._find(q);
if (pRoot == qRoot) {
return;
}
if (this._rank[pRoot] < this._rank[qRoot]) {
this._parent[pRoot] = qRoot;
} else if (this._rank[pRoot] > this._rank[qRoot]) {
this._parent[qRoot] = pRoot;
} else {
this._parent[qRoot] = pRoot;
this._rank[pRoot] += 1;
}
}
}
export default UnionFind;
哈希表
class HashTable {
constructor(capacity) {
if (!capacity) {
throw new RangeError("capacity is empty");
}
this._data = new Array(capacity);
this._size = 0;
for (let i=0; i<capacity; i++) {
this._data[i] = {};
}
}
hashCode(key) {
let hash = 5381;
for (let i = 0; i < key.length; i++) {
hash = ((hash << 5) + hash) + key.charCodeAt(i);
}
return Math.abs(hash % this._data.length);
}
get size() {
return this._size;
}
add(key, value) {
let map = this._data[this.hashCode(key)];
if (map[key]) {
map[key] = value;
} else {
map[key] = value;
this._size++;
}
}
remove(key) {
let map = this._data[this.hashCode(key)];
let ret = map[key];
if (map[key]) {
delete map[key];
this._size--;
}
return ret;
}
get(key) {
return this._data[this.hashCode(key)][key];
}
set(key, value) {
let map = this._data[this.hashCode(key)];
if (!map[key]) {
throw new RangeError("key is not found");
}
map[key] = value;
}
contains(key) {
return !!(this.get(key));
}
}
export default HashTable;
图
class Graph {
constructor() {
this._vertices = [];
this._adjList = {};
}
get size() {
return this._vertices.length;
}
get isEmpty() {
return this.size == 0;
}
contains(v) {
return this._vertices.includes(v);
}
addVertex(v) {
if (!this.contains(v)) {
this._vertices.push(v);
this._adjList[v] = [];
}
}
addEdge(v, e) {
if (!this.contains(v)) {
throw new RangeError(`${v} is not exist`);
}
if (!this.contains(e)) {
throw new RangeError(`${e} is not exist`);
}
if (Object.is(v, e)) {
throw new RangeError(`${v} == ${e}, can't point to self`);
}
this._adjList[v].push(e);
this._adjList[e].push(v);
}
removeVertex(v) {
if (this.contains(v)) {
for (let key in this._adjList) {
let edge = this._adjList[key];
if (edge.includes(v)) {
edge.splice(edge.indexOf(v),1);
}
}
this._vertices.splice(this._vertices.indexOf(v),1);
delete this._adjList[v];
return v;
}
}
removeEdge(v1, v2) {
let v1Edge = this._adjList[v1];
let v2Edge = this._adjList[v2];
if (!v1Edge) {
throw new RangeError(v1+"is not exist");
}
for (let i=0; i<v1Edge.length; i++) {
if (v1Edge.includes(v2)) {
v1Edge.splice(v1Edge.indexOf(v2),1);
}
}
for (let i=0; i<v2Edge.length; i++) {
if (v2Edge.includes(v1)) {
v2Edge.splice(v2Edge.indexOf(v1),1);
}
}
}
getEdge(v) {
return this._adjList[v];
}
isConnected(v1, v2) {
let v1Edge = this._adjList[v1];
let v2Edge = this._adjList[v2];
if (!v1Edge) {
throw new RangeError(`${v1} is not exist`);
}
if (!v2Edge) {
throw new RangeError(`${v2} is not exist`);
}
if (v1Edge.includes(v2) && v2Edge.includes(v1)) {
return true;
}
return false;
}
toString() {
let res = "";
let edge = this._adjList;
for (let key in edge) {
res += key+" -> [";
edge[key].forEach((item,index) => {
res += item;
if (index != edge[key].length-1) {
res += " ";
}
});
res += "]\n";
}
return res;
}
}
export default Graph;