存储
集合
class Set {
constructor ( ) {
this . _list = [ ]
}
get size ( ) {
return this . _list. length;
}
get isEmpty ( ) {
return this . _list. length === 0 ;
}
add ( e) {
if ( ! this . _list. includes ( e) ) {
this . _list. push ( e)
}
return this ;
}
delete ( e) {
let list = this . _list;
let index = list. indexOf ( e)
if ( index != - 1 ) {
list. splice ( index, 1 )
}
return index != - 1 ;
}
has ( e) {
return this . _list. includes ( e)
}
clear ( ) {
this . _list. length = 0 ;
}
iterator ( ) {
let _this = this ;
return {
_i: 0 ,
next ( ) {
if ( this . hasNext ( ) ) {
return _this. _list[ this . _i++ ] ;
}
} ,
hasNext ( ) {
return this . _i !== _this. size;
}
}
}
}
链表
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 size ( ) {
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) ;
if ( this . _size === index) {
this . _tail = cur. next;
}
this . _size++ ;
}
unshift ( e) {
this . _dummyhead. next = new LinkedListNode ( e, this . _dummyhead. next) ;
if ( this . _size == 0 ) {
this . _tail = this . _dummyhead. next;
}
this . _size++ ;
}
push ( 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;
}
pop ( ) {
return this . removeIndex ( this . _size- 1 ) ;
}
shift ( ) {
return this . removeIndex ( 0 ) ;
}
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;
}
iterator ( ) {
return {
_item: this . _dummyhead,
next ( ) {
if ( this . hasNext ( ) ) {
let ret = this . _item. next;
this . _item = this . _item. next;
return ret;
}
return null ;
} ,
hasNext ( ) {
return this . _item. next !== null ;
}
}
}
}
双向链表
class LinkedListNode {
constructor ( item, next = null , prev = null ) {
this . item = item;
this . next = next;
this . prev = prev;
}
}
class LinkedList {
constructor ( ) {
this . _dummyhead = new LinkedListNode ( null ) ;
this . _tail = null ;
this . _size = 0 ;
}
get size ( ) {
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, cur) ;
if ( cur. next. next) {
cur. next. next. prev = cur. next;
}
if ( this . _size === index) {
this . _tail = cur. next;
}
this . _size++ ;
}
unshift ( e) {
this . _dummyhead. next = new LinkedListNode ( e, this . _dummyhead. next) ;
if ( this . _size == 0 ) {
this . _tail = this . _dummyhead. next;
}
this . _size++ ;
}
push ( e) {
if ( this . _size == 0 ) {
this . _dummyhead. next = new LinkedListNode ( e, null , this . _dummyhead) ;
this . _tail = this . _dummyhead. next;
} else {
this . _tail. next = new LinkedListNode ( e, null , this . _tail) ;
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 ( prev. next !== null && Object. is ( prev. next. item, e) ) {
break ;
}
prev = prev. next;
}
if ( prev != null ) {
let ret = prev. next;
prev. next = ret. next;
if ( ret. next) {
ret. next. prev = prev;
}
ret. next = null ;
if ( Object. is ( ret. item, this . _tail. item) ) {
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;
if ( ret. next) {
ret. next. prev = prev;
}
ret. next = null ;
if ( Object. is ( ret. item, this . _tail. item) ) {
this . _tail = prev;
}
this . _size-- ;
return ret;
}
pop ( ) {
return this . removeIndex ( this . size - 1 ) ;
}
shift ( ) {
return this . removeIndex ( 0 ) ;
}
find ( e) {
let cur = this . _dummyhead. next;
let index = 0 ;
while ( cur !== null ) {
if ( Object. is ( cur. item, 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. item;
if ( i != len - 1 ) {
res += " > " ;
}
cur = cur. next;
}
return res;
}
iterator ( ) {
return {
_item: this . _dummyhead,
next ( ) {
if ( this . hasNext ( ) ) {
let ret = this . _item. next;
this . _item = this . _item. next;
return ret;
}
return null ;
} ,
hasNext ( ) {
return this . _item. next !== null ;
}
}
}
}
队列
class Queue {
constructor ( ) {
this . list = [ ] ;
}
enqueue ( item) {
this . list. push ( item) ;
}
dequeue ( ) {
return this . list. shift ( ) ;
}
get isEmpty ( ) {
return this . list. length === 0 ;
}
get size ( ) {
return this . list. length;
}
}
栈
class Stack {
constructor ( ) {
this . list = [ ] ;
}
get isEmpty ( ) {
return this . list. length=== 0 ;
}
get size ( ) {
return this . list. length;
}
push ( item) {
this . list. push ( item) ;
}
pop ( ) {
return this . list. pop ( ) ;
}
}
class PriorityQueue {
constructor ( ) {
this . _list = new MaxHeap ( ) ;
}
get size ( ) {
return this . _list. size;
}
get isEmpty ( ) {
return this . _list. isEmpty;
}
get top ( ) {
return this . _list. max;
}
enqueue ( e) {
this . _list. push ( e)
}
dequeue ( ) {
return this . _list. pop ( ) ;
}
}
最大堆
class MaxHeap {
constructor ( ) {
this . data = [ ] ;
}
get isEmpty ( ) { return this . data. length === 0 }
get size ( ) { return this . data. length}
get max ( ) {
return this . data[ 0 ] ;
}
swap ( x, y) {
let temp = this . data[ x]
this . data[ x] = this . data[ y]
this . data[ y] = temp;
}
parent ( index) {
return Math. floor ( ( index - 1 ) / 2 ) ;
}
leftChild ( index) {
return index * 2 + 1 ;
}
rightChild ( index) {
return index * 2 + 2 ;
}
push ( e) {
this . data. push ( e) ;
this . siftUp ( this . size - 1 ) ;
}
siftUp ( k) {
while ( k > 0 && this . data[ this . parent ( k) ] < this . data[ k] ) {
this . swap ( k, this . parent ( k) ) ;
k = this . parent ( k) ;
}
}
pop ( ) {
let ret = this . max;
this . swap ( 0 , this . size - 1 ) ;
this . data. pop ( ) ;
this . siftDown ( 0 ) ;
return ret;
}
siftDown ( k) {
while ( this . leftChild ( k) < this . size) {
let j = this . leftChild ( k) ;
if ( j + 1 < this . size && this . data[ j+ 1 ] > this . data[ j] )
j ++ ;
if ( this . data[ k] >= this . data[ j] )
break ;
this . swap ( k, j) ;
k = j;
}
}
}
最小堆
class MinHeap {
constructor ( ) {
this . data = [ ] ;
}
get isEmpty ( ) { return this . data. length === 0 }
get size ( ) { return this . data. length}
get min ( ) {
return this . data[ 0 ] ;
}
swap ( x, y) {
let temp = this . data[ x]
this . data[ x] = this . data[ y]
this . data[ y] = temp;
}
parent ( index) {
return Math. floor ( ( index - 1 ) / 2 ) ;
}
leftChild ( index) {
return index * 2 + 1 ;
}
rightChild ( index) {
return index * 2 + 2 ;
}
push ( e) {
this . data. push ( e) ;
this . siftUp ( this . size - 1 ) ;
}
siftUp ( k) {
while ( k > 0 && this . data[ this . parent ( k) ] > this . data[ k] ) {
this . swap ( k, this . parent ( k) ) ;
k = this . parent ( k) ;
}
}
pop ( ) {
let ret = this . min;
this . swap ( 0 , this . size - 1 ) ;
this . data. pop ( ) ;
this . siftDown ( 0 ) ;
return ret;
}
siftDown ( k) {
while ( this . leftChild ( k) < this . size) {
let j = this . leftChild ( k) ;
if ( j + 1 < this . size && this . data[ j+ 1 ] < this . data[ j] )
j ++ ;
if ( this . data[ k] <= this . data[ j] )
break ;
this . swap ( k, j) ;
k = j;
}
}
}
图
class Graph {
constructor ( V = 10 ) {
this . V = V ;
this . E = 0 ;
this . adj = [ ] ;
for ( let i= 0 ; i< V ; i++ ) {
this . adj[ i] = new Set ( )
}
}
addEdge ( v, w) {
this . adj[ v] . add ( w)
this . adj[ w] . add ( v)
this . E ++ ;
}
Iterable ( v) { return this . adj[ v] }
}
class BreadthFirstPaths {
constructor ( graph, s) {
this . marked = [ ] ;
this . edgeTo = [ ] ;
this . s = s;
this . bfs ( graph, s)
}
bfs ( graph, s) {
let queue = [ s] ;
this . marked[ s] = true ;
while ( queue. length != 0 ) {
s = queue. shift ( ) ;
graph. Iterable ( s) . forEach ( item=> {
if ( ! this . marked[ item] ) {
this . marked[ item] = true ;
this . edgeTo[ item] = s;
queue. push ( item)
}
} )
}
}
shortest ( v) {
if ( ! this . marked[ v] ) return null ;
let path = [ ] ;
for ( let x= v; x!= this . s; x= this . edgeTo[ x] ) {
path. unshift ( x)
}
path. unshift ( this . s)
return path;
}
}
class DepthFirstPaths {
constructor ( graph, s) {
this . marked = [ ] ;
this . edgeTo = [ ] ;
this . s = s;
this . dfs ( graph, s) ;
}
dfs ( graph, v) {
this . marked[ v] = true ;
graph. Iterable ( v) . forEach ( item=> {
if ( ! this . marked[ item] ) {
this . edgeTo[ item] = v;
this . dfs ( graph, item)
}
} )
}
hasPathTo ( v) {
return this . marked[ v]
}
pathTo ( v) {
if ( ! this . hasPathTo ( v) ) return null ;
let path = [ ] ;
for ( let x= v; x!= this . s; x= this . edgeTo[ x] ) {
path. unshift ( x)
}
path. unshift ( this . s)
return path;
}
}
class CC {
constructor ( graph) {
this . marked = [ ] ;
this . _id = [ ] ;
this . _count = 0 ;
for ( let s= 0 ; s< graph. V ; s++ ) {
if ( ! this . marked[ s] ) {
this . dfs ( graph, s)
this . _count++ ;
}
}
}
dfs ( graph, v) {
if ( ! this . marked[ v] ) {
this . marked[ v] = true ;
this . _id[ v] = this . _count;
graph. Iterable ( v) . forEach ( item=> {
if ( ! this . marked[ s] ) {
this . dfs ( graph, item)
}
} )
}
}
connected ( v, w) {
return this . _id[ v] == this . _id[ w]
}
id ( v) { return this . _id[ v] }
get count ( ) { return this . _count}
}
查找
二分查找树
class Node {
constructor ( key, value, size = 0 ) {
this . key = key;
this . value = value;
this . size = size;
this . left = this . right = null ;
}
}
class BST {
constructor ( ) {
this . root = null ;
}
get size ( ) {
return this . _getSize ( this . root) ;
}
_getSize ( node) {
if ( node === null ) {
return 0 ;
} else {
return node. size;
}
}
get ( key) {
function _get ( node, key) {
if ( node === null ) return null ;
if ( key > node. key) {
return _get ( node. right, key) ;
} else if ( key < node. key) {
return _get ( node. left, key) ;
} else {
return node. value;
}
}
key = this . _strToNum ( key) ;
return _get ( this . root, key) ;
}
put ( key, value) {
let _this = this ;
key = this . _strToNum ( key) ;
this . root = _put ( this . root, key, value) ;
function _put ( node, key, value) {
if ( node === null ) { return new Node ( key, value) } ;
if ( key < node. key) {
node. left = _put ( node. left, key, value) ;
} else if ( key > node. key) {
node. right = _put ( node. right, key, value) ;
} else {
node. value = value;
}
node. size = _this. _getSize ( node. left) + _this. _getSize ( node. right) + 1 ;
return node;
}
}
contains ( key) {
return this . get ( key) !== null ;
}
delete ( key) {
let ret = null ;
let _this = this ;
key = this . _strToNum ( key) ;
function _delete ( node, key) {
if ( node === null ) { return null }
if ( key < node. key) {
node. left = _delete ( node. left, key) ;
} else if ( key > node. key) {
node. right = _delete ( node. right, key)
} else {
ret = node;
if ( node. right === null ) return node. left;
if ( node. left === null ) return node. right;
node = _this. _min ( node. right) ;
_this. _deleteMin ( node. right) ;
}
node. size = _this. _getSize ( node. left) + _this. _getSize ( node. right) + 1 ;
return node;
}
this . root = _delete ( this . root, key) ;
return ret;
}
preOrder ( ) {
_preOrder ( this . root) ;
function _preOrder ( node) {
if ( node == null ) {
return ;
}
console. log ( node. value) ;
_preOrder ( node. left) ;
_preOrder ( node. right) ;
}
}
inOrder ( ) {
_inOrder ( this . root) ;
function _inOrder ( node) {
if ( node == null ) {
return ;
}
_inOrder ( node. left) ;
console. log ( node. value) ;
_inOrder ( node. right) ;
}
}
postOrder ( ) {
_postOrder ( this . root) ;
function _postOrder ( node) {
if ( node == null ) {
return ;
}
_postOrder ( node. left) ;
_postOrder ( node. right) ;
console. log ( node. value) ;
}
}
levelOrder ( ) {
let queue = [ ] ;
let node;
queue. push ( this . root) ;
while ( queue. length) {
node = queue. shift ( ) ;
console. log ( node. value) ;
if ( node. left != null ) {
queue. push ( node. left) ;
}
if ( node. right != null ) {
queue. push ( node. right) ;
}
}
}
_min ( node = this . root) {
if ( node === null ) { return null }
return _min ( node) ;
function _min ( node) {
if ( node. left === null ) return node;
return _min ( node. left) ;
}
}
_deleteMin ( node = this . root) {
let ret = this . _min ( this . root) ;
let _this = this ;
if ( ret === null ) { return null }
this . root = _deleteMin ( node) ;
return ret;
function _deleteMin ( node) {
if ( node === null ) { return node }
if ( node. left === null ) {
node = node. right;
} else if ( node. left. left === null ) {
node. left = node. left. right;
} else {
node. left = _deleteMin ( node. left) ;
}
if ( node) {
node. size = _this. _getSize ( node. left) + _this. _getSize ( node. right) + 1 ;
}
return node;
}
}
_strToNum ( key) {
if ( typeof key !== "string" ) { throw ( "key need string type" ) }
let num = "" ;
for ( let i = 0 ; i < key. length; i++ ) {
num += String ( key. charAt ( i) . charCodeAt ( ) ) ;
}
return Number ( num) ;
}
}
AVL
class Node {
constructor ( key, value, height = 1 ) {
this . key = key;
this . value = value;
this . height = height;
this . left = this . right = null ;
}
}
class AVL {
constructor ( ) {
this . root = null ;
}
get height ( ) {
return this . _getHeight ( this . root) ;
}
_getHeight ( node) {
if ( node === null ) {
return 0 ;
} else { return node. height}
}
_leftRotate ( node) {
let n = node;
node = node. right;
n. right = node. left;
node. left = n;
n. height = Math. max ( this . _getHeight ( n. left) , this . _getHeight ( n. right) ) + 1 ;
node. height = Math. max ( this . _getHeight ( node. left) , this . _getHeight ( node. right) ) + 1 ;
return node;
}
_rightRotate ( node) {
let n = node;
node = node. left;
n. left = node. right;
node. right = n;
n. height = Math. max ( this . _getHeight ( n. left) , this . _getHeight ( n. right) ) + 1 ;
node. height = Math. max ( this . _getHeight ( node. left) , this . _getHeight ( node. right) ) + 1 ;
return node;
}
_rlRotate ( node) {
node. right = this . _rightRotate ( node. right) ;
node = this . _leftRotate ( node) ;
return node;
}
_lrRotate ( node) {
node. left = this . _leftRotate ( node. left) ;
node = this . _rightRotate ( node) ;
return node;
}
_getBalanceFactor ( node) {
if ( node == null ) {
return 0 ;
}
return this . _getHeight ( node. left) - this . _getHeight ( node. right) ;
}
_rotate ( node) {
let balanceFactor = this . _getBalanceFactor ( node) ;
if ( Math. abs ( balanceFactor) > 1 ) {
if ( balanceFactor > 1 && this . _getBalanceFactor ( node. left) >= 0 ) {
node = this . _rightRotate ( node) ;
}
if ( balanceFactor < - 1 && this . _getBalanceFactor ( node. right) <= 0 ) {
node = this . _leftRotate ( node) ;
}
if ( balanceFactor > 1 && this . _getBalanceFactor ( node. left) < 0 ) {
node = this . _lrRotate ( node) ;
}
if ( balanceFactor < - 1 && this . _getBalanceFactor ( node. right) > 0 ) {
node = this . _rlRotate ( node) ;
}
}
return node;
}
get ( key) {
function _get ( node, key) {
if ( node === null ) return null ;
if ( key > node. key) {
return _get ( node. right, key) ;
} else if ( key < node. key) {
return _get ( node. left, key) ;
} else {
return node. value;
}
}
key = this . _strToNum ( key) ;
return _get ( this . root, key) ;
}
put ( key, value) {
let _this = this ;
key = this . _strToNum ( key) ;
this . root = _put ( this . root, key, value) ;
function _put ( node, key, value) {
if ( node === null ) { return new Node ( key, value) } ;
if ( key < node. key) {
node. left = _put ( node. left, key, value) ;
} else if ( key > node. key) {
node. right = _put ( node. right, key, value) ;
} else {
node. value = value;
}
node. height = Math. max ( _this. _getHeight ( node. left) , _this. _getHeight ( node. right) ) + 1 ;
return _this. _rotate ( node) ;
}
}
contains ( key) {
return this . get ( key) !== null ;
}
delete ( key) {
let ret = null ;
let _this = this ;
key = this . _strToNum ( key) ;
function _delete ( node, key) {
if ( node === null ) { return null }
if ( key < node. key) {
node. left = _delete ( node. left, key) ;
} else if ( key > node. key) {
node. right = _delete ( node. right, key)
} else {
ret = node;
if ( node. right === null ) return node. left;
if ( node. left === null ) return node. right;
node = _this. _min ( node. right) ;
_this. _deleteMin ( node. right) ;
}
node. height = Math. max ( _this. _getHeight ( node. left) , _this. _getHeight ( node. right) ) + 1 ;
return _this. _rotate ( node) ;
}
this . root = _delete ( this . root, key) ;
return ret;
}
preOrder ( ) {
_preOrder ( this . root) ;
function _preOrder ( node) {
if ( node == null ) {
return ;
}
console. log ( node. value) ;
_preOrder ( node. left) ;
_preOrder ( node. right) ;
}
}
inOrder ( ) {
_inOrder ( this . root) ;
function _inOrder ( node) {
if ( node == null ) {
return ;
}
_inOrder ( node. left) ;
console. log ( node. value) ;
_inOrder ( node. right) ;
}
}
postOrder ( ) {
_postOrder ( this . root) ;
function _postOrder ( node) {
if ( node == null ) {
return ;
}
_postOrder ( node. left) ;
_postOrder ( node. right) ;
console. log ( node. value) ;
}
}
levelOrder ( ) {
let queue = [ ] ;
let node;
queue. push ( this . root) ;
while ( queue. length) {
node = queue. shift ( ) ;
console. log ( node. value) ;
if ( node. left != null ) {
queue. push ( node. left) ;
}
if ( node. right != null ) {
queue. push ( node. right) ;
}
}
}
_min ( node = this . root) {
if ( node === null ) { return null }
return _min ( node) ;
function _min ( node) {
if ( node. left === null ) return node;
return _min ( node. left) ;
}
}
_deleteMin ( node = this . root) {
let ret = this . _min ( this . root) ;
let _this = this ;
if ( ret === null ) { return null }
this . root = _deleteMin ( node) ;
return ret;
function _deleteMin ( node) {
if ( node === null ) { return node }
if ( node. left === null ) {
node = node. right;
} else if ( node. left. left === null ) {
node. left = node. left. right;
} else {
node. left = _deleteMin ( node. left) ;
}
if ( node) {
node. size = _this. _getSize ( node. left) + _this. _getSize ( node. right) + 1 ;
}
return node;
}
}
_strToNum ( key) {
if ( typeof key !== "string" ) { throw ( "key need string type" ) }
let num = "" ;
for ( let i = 0 ; i < key. length; i++ ) {
num += String ( key. charAt ( i) . charCodeAt ( ) ) ;
}
return Number ( num) ;
}
}
红黑树
const RED = true ;
const BLACK = false ;
class Node {
constructor ( key, value) {
this . key = key;
this . value = value;
this . left = null ;
this . right = null ;
this . color = RED ;
}
}
class RBTree {
constructor ( ) {
this . root = null ;
this . size = 0 ;
}
get getsize ( ) {
return this . size;
}
get isEmpty ( ) {
return this . size == 0 ;
}
put ( key, value) {
let _this = this ;
this . root = put ( this . root, this . _strToNum ( key) , value) ;
this . root. color = BLACK ;
function put ( node, key, value) {
if ( node == null ) {
_this. size++ ;
return new Node ( key, value) ;
}
if ( key < node. key) {
node. left = put ( node. left, key, value) ;
} else if ( key > node. key) {
node. right = put ( node. right, key, value) ;
} else {
node. value = value;
}
if ( _this. isRed ( node. right) && ! _this. isRed ( node. left) ) {
node = _this. leftRotate ( node) ;
}
if ( _this. isRed ( node. left) && _this. isRed ( node. left. left) ) {
node = _this. rightRotate ( node) ;
}
if ( _this. isRed ( node. left) && _this. isRed ( node. right) ) {
_this. flipColors ( node) ;
}
return node;
}
}
remove ( key) {
let node = this . getNode ( this . root, this . _strToNum ( key) ) ;
let _this = this ;
if ( node != null ) {
this . root = remove ( this . root, this . _strToNum ( key) ) ;
return node. value;
}
function remove ( node, key) {
if ( node == null ) {
return null ;
}
if ( key < node. key) {
node. left = remove ( node. left, key) ;
return node;
} else if ( key > node. key) {
node. right = remove ( node. right, key) ;
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;
} else {
let successor = _this. minimum ( node. right) ;
successor. right = _this. removeMin ( node. right) ;
successor. left = node. left;
node. left = node. right = null ;
return successor;
}
}
}
return null ;
}
get ( key) {
let node = this . getNode ( this . root, this . _strToNum ( key) ) ;
return node == null ? null : node. value;
}
contains ( key) {
return this . getNode ( this . root, this . _strToNum ( key) ) != null ;
}
preOrder ( ) {
_preOrder ( this . root) ;
function _preOrder ( node) {
if ( node == null ) {
return ;
}
console. log ( node. value) ;
_preOrder ( node. left) ;
_preOrder ( node. right) ;
}
}
inOrder ( ) {
_inOrder ( this . root) ;
function _inOrder ( node) {
if ( node == null ) {
return ;
}
_inOrder ( node. left) ;
console. log ( node. value) ;
_inOrder ( node. right) ;
}
}
postOrder ( ) {
_postOrder ( this . root) ;
function _postOrder ( node) {
if ( node == null ) {
return ;
}
_postOrder ( node. left) ;
_postOrder ( node. right) ;
console. log ( node. value) ;
}
}
levelOrder ( ) {
let queue = [ ] ;
let node;
queue. push ( this . root) ;
while ( queue. length) {
node = queue. shift ( ) ;
console. log ( node. value) ;
if ( node. left != null ) {
queue. push ( node. left) ;
}
if ( node. right != null ) {
queue. push ( node. right) ;
}
}
}
leftRotate ( node) {
let x = node. right;
node. right = x. left;
x. left = node;
x. color = node. color;
node. color = RED ;
return x;
}
rightRotate ( node) {
let x = node. left;
node. left = x. right;
x. right = node;
x. color = node. color;
node. color = RED ;
return x;
}
flipColors ( node) {
node. color = RED ;
node. right. color = BLACK ;
node. left. color = BLACK ;
}
isRed ( node) {
if ( node == null ) {
return BLACK ;
}
return node. color;
}
_strToNum ( key) {
if ( typeof key !== "string" ) { throw ( "key need string type" ) }
let num = "" ;
for ( let i = 0 ; i < key. length; i++ ) {
num += String ( key. charAt ( i) . charCodeAt ( ) ) ;
}
return Number ( num) ;
}
minimum ( node = this . root) {
if ( this . size === 0 ) throw ( "size 0" ) ;
return minimum ( node) ;
function minimum ( node) {
if ( node. left == null ) {
return node;
}
return minimum ( node. left) ;
}
}
removeMin ( node = this . root) {
let _this = this ;
return removeMin ( node) ;
function removeMin ( node) {
if ( node. left == null ) {
let rightNode = node. right;
node. right = null ;
_this. size-- ;
return rightNode;
}
node. left = removeMin ( node. left) ;
return node;
}
}
getNode ( node, key) {
if ( node == null ) {
return null ;
}
if ( key == node. key) {
return node;
} else if ( key < node. key) {
return this . getNode ( node. left, key) ;
} else {
return this . getNode ( node. right, key) ;
}
}
}
并查集
class UnionFind {
constructor ( size) {
this . _parent = new Array ( size) ;
this . _rank = new Array ( size) ;
for ( let i= 0 ; i< size; 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 Error ( "p is out of bound" ) ;
}
let parent = this . _parent;
while ( p != parent[ p] ) {
parent[ p] = parent[ parent[ p] ] ;
p = parent[ p] ;
}
return p;
}
isConnected ( p, q) {
return this . find ( p) == this . find ( q) ;
}
unionElements ( p, q) {
let pRoot = this . find ( p) ;
let qRoot = this . find ( q) ;
let rank = this . _rank;
let parent = this . _parent;
if ( pRoot == qRoot) {
return ;
}
if ( rank[ pRoot] < rank[ qRoot] ) {
parent[ pRoot] = qRoot;
} else if ( rank[ pRoot] > rank[ qRoot] ) {
parent[ qRoot] = pRoot;
} else {
parent[ qRoot] = pRoot;
rank[ pRoot] += 1 ;
}
}
}
字典树
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;
}
delete ( word) {
if ( this . contains ( word) ) {
let cur = this . _root;
for ( let i = 0 ; i < word. length; i++ ) {
let key = word. charAt ( i) ;
cur = cur. next[ key] ;
}
cur. isWord = false ;
}
}
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 ;
}
iterator ( ) {
let cur = this . _root;
let ret = [ ] ;
let w = "" ;
function each ( next) {
for ( let key in next) {
let word = next[ key] ;
w += key;
if ( word. isWord) {
ret. push ( w)
w = "" ;
}
if ( word. next) {
each ( word. next)
}
}
}
each ( cur. next) ;
return ret;
}
}
哈希表
class HashTable {
constructor ( capacity) {
if ( ! capacity) {
throw new RangeError ( "capacity is empty" ) ;
}
this . _data = new Array ( capacity) ;
this . _size = 0 ;
}
hashCode ( key) {
let hash = 5381 ;
key = String ( key) ;
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 hashCode = this . hashCode ( key) ;
let map = this . _data[ hashCode] ;
if ( map === undefined) {
this . _data[ hashCode] = {
[ key] : value
}
} else {
map[ key] = value;
}
this . _size++ ;
}
remove ( key) {
let map = this . _data[ this . hashCode ( key) ] ;
let ret = map[ key] ;
if ( map) {
delete map[ key] ;
this . _size-- ;
}
return ret;
}
get ( key) {
let hashCode = this . hashCode ( key) ;
let map = this . _data[ hashCode] ;
return map ? map[ key] : undefined;
}
set ( key, value) {
let map = this . _data[ this . hashCode ( key) ] ;
if ( ! map) {
throw new RangeError ( "key is not found" ) ;
}
map[ key] = value;
}
contains ( key) {
return ! ! ( this . get ( key) ) ;
}
}
映射
class Node {
constructor ( key, value, prev= null , next= null ) {
this . key = key;
this . value = value;
this . next = next;
this . prev = prev;
}
}
class LinkedListMap {
constructor ( ) {
this . _root = null ;
this . _tail = null ;
this . _size = 0 ;
}
get size ( ) { return this . _size}
get isEmpty ( ) { return this . _size === 0 }
contains ( key) {
if ( typeof key !== "string" ) { throw ( "key need string type" ) }
for ( let cur= this . _root; cur!= null ; cur= cur. next) {
if ( cur. key === key) {
return cur;
}
}
return null ;
}
get ( key) {
if ( typeof key !== "string" ) { throw ( "key need string type" ) }
let ret = this . contains ( key) ;
return ret ? ret. value : null ;
}
put ( key, value) {
if ( typeof key !== "string" ) { throw ( "key need string type" ) }
let ret = this . contains ( key) ;
if ( ret !== null ) {
ret. value = value;
} else {
let node = new Node ( key, value) ;
if ( this . size === 0 ) {
this . _root = node;
this . _tail = node;
} else {
node. prev = this . _tail;
this . _tail. next = node;
this . _tail = node;
}
this . _size++ ;
}
}
delete ( key) {
if ( typeof key !== "string" ) { throw ( "key need string type" ) }
let node = this . contains ( key) ;
if ( node !== null ) {
if ( key === this . _root. key) {
let next = this . _root. next;
this . _root. next = null ;
this . _root = next;
if ( next != null ) {
next. prev = null ;
} else {
this . _tail = null
}
} else {
node. prev. next = node. next;
if ( key === this . _tail. key) {
this . _tail = node. prev;
} else {
node. next = null ;
node. next. prev = null ;
}
}
this . _size-- ;
}
}
}
参考资料
《算法(第四版)》