UNPKG

3.25 kBPlain TextView Raw
1import { LinkList } from "../linklist/LinkList";
2import { BasicBinaryTree } from "../tree/basic-binary-tree/BasicBinaryTree";
3import { RedBlackTree } from "../tree/red-black-tree/RedBlackTree";
4import { hash, toString } from "../util";
5
6export class TreeMap<K= string, T= any>{
7 private size = 0;
8 private tree: RedBlackTree<{key: number|K, value?: LinkList<{key: K, value: T}>}>;
9
10 constructor(){
11 this.tree = new RedBlackTree("key");
12 }
13
14 get Count() {
15 return this.size;
16 }
17
18 put(key: K, value: T) {
19 let link = this.get(key);
20 if (link){
21 // 判断是否在链表中存在
22 const node = link.findNode(item => item.key === key);
23 if (node){
24 node.Value.value = value;
25 return this;
26 }
27 link.append({key, value});
28 this.size ++;
29 return this;
30 }
31 // 先++,需要hashmod
32 this.size ++;
33 const hashKey = this.getHashKey(key);
34 const treeNode = this.tree.insert({
35 key: hashKey,
36 });
37 link = new LinkList<{key: K, value: T}>();
38 link.append({key, value});
39 treeNode.Value.value = link;
40 return this;
41 }
42
43 private get(key: K) {
44 const hashKey = this.getHashKey(key);
45 const node = this.tree.find({key: hashKey});
46 if (node){
47 return node.Value.value;
48 }
49 return null;
50 }
51
52 getVal(key: K){
53 const hashKey = this.getHashKey(key);
54 const node = this.tree.find({key: hashKey});
55 if (node){
56 const link = node.Value.value;
57 const val = link.findNode(item => item.key === key);
58 if (!val){
59 return null;
60 }
61 return val.Value.value;
62 }
63 return null;
64 }
65
66 clear() {
67 this.size = 0;
68 return this.tree.clear();
69 }
70
71 remove(key: K) {
72 const hashKey = this.getHashKey(key);
73 const node = this.get(key);
74 if (node){
75 const success = node.deleteNode(item => item.key === key);
76 if (success){
77 this.size --;
78 if (node.Size === 0){
79 return this.tree.remove({key: hashKey});
80 }
81 return true;
82 }
83 }
84 return false;
85 }
86
87 keys() {
88 return BasicBinaryTree.inTraversal(this.tree.Root)
89 .map(item => item.value).reduce((ori: Array<K>, item: LinkList<{key: K, value: T}>) => {
90 return ori.concat(item.toArray().map(node => node.Value.key));
91 }, []);
92 }
93
94 values() {
95 return BasicBinaryTree.inTraversal(this.tree.Root)
96 .map(item => item.value).reduce((ori: Array<T>, item: LinkList<{key: K, value: T}>) => {
97 return ori.concat(item.toArray().map(node => node.Value.value));
98 }, []);
99 }
100
101 contains(key: K) {
102 return this.tree.contains({key});
103 }
104
105 private getHashKey(key: K): number|K{
106 // 数值和字符串直接比较大小
107 if (typeof key === "number" || typeof key === "string"){
108 return key;
109 }
110 const hashKey = hash(toString(key));
111 return hashKey;
112 }
113}