目的:ES6标准下的JS数据结构的一些实现代码。(作为记录和启发)
内容:图,图的遍历(广度优先搜索BFS,深度优先搜索DFS),。(未完成,待继续)
一、基础数据结构
1、图(创建Graph类)
1 // import dictionary 2 class ValuePair { 3 constructor(key, value) { 4 this.key = key; 5 this.value = value; 6 } 7 8 toString() { 9 return `[#${this.key}: ${this.value}]`; 10 } 11 } 12 13 function defaultToString(item) { 14 if (item === null) { 15 return 'NULL'; 16 } if (item === undefined) { 17 return 'UNDEFINED'; 18 } if (typeof item === 'string' || item instanceof String) { 19 return `${item}`; 20 } 21 return item.toString(); 22 } 23 24 class Dictionary { 25 constructor(toStrFn = defaultToString) { 26 this.toStrFn = toStrFn; 27 this.table = {}; 28 } 29 hasKey(key) { 30 return this.table[this.toStrFn(key)] != null; 31 } 32 set(key, value) { 33 if (key != null && value != null) { 34 const tableKey = this.toStrFn(key); 35 this.table[tableKey] = new ValuePair(key,value); 36 return true; 37 } 38 return false; 39 } 40 remove(key) { 41 if (this.hasKey(key)) { 42 delete this.table[this.toStrFn(key)]; 43 return true; 44 } 45 return false; 46 } 47 get(key) { 48 const valuePair = this.table[this.toStrFn(key)]; 49 return valuePair == null ? undefined : valuePair.value; 50 } 51 keyValues() { 52 return Object.values(this.table); 53 } 54 values() { 55 return this.keyValues().map(valuePair => valuePair.value); 56 } 57 58 keys() { 59 return this.keyValues().map(valuePair => valuePair.key); 60 } 61 forEach(callbackFn) { 62 const valuePairs = this.keyValues(); 63 for (let i = 0; i < valuePairs.length; i++) { 64 const result = callbackFn(valuePairs[i].key, valuePairs[i].value); 65 if (result === false) { 66 break; 67 } 68 } 69 } 70 71 isEmpty() { 72 return this.size() === 0; 73 } 74 75 size() { 76 return Object.keys(this.table).length; 77 } 78 79 clear() { 80 this.table = {}; 81 } 82 83 toString() { 84 if (this.isEmpty()) { 85 return ''; 86 } 87 const valuePairs = this.keyValues(); 88 let objString = `${valuePairs[0].toString()}`; 89 for (let i = 1; i < valuePairs.length; i++) { 90 objString = `${objString},${valuePairs[i].toString()}`; 91 } 92 return objString; 93 } 94 95 96 } 97 98 class Graph { 99 constructor (isDirected = false) { 100 this.isDirected = isDirected; 101 this.vertices = []; 102 this.adjList = new Dictionary(); 103 } 104 addVertex(v) { 105 if (!this.vertices.includes(v)) { 106 this.vertices.push(v); 107 this.adjList.set(v, []); 108 } 109 } 110 addEdge(a, b ) { 111 if (!this.adjList.get(a)) { 112 this.addVertex(a); 113 } 114 if (!this.adjList.get(b)) { 115 this.adjList(b); 116 } 117 this.adjList.get(a).push(b); 118 if (this.isDirected !== true) { 119 this.adjList.get(b).push(a); 120 } 121 } 122 getVertices() { 123 return this.vertices; 124 } 125 getAdjList() { 126 return this.adjList; 127 } 128 toString() { 129 let s = ''; 130 for (let i = 0; i < this.vertices.length; i++) { 131 s += `${this.vertices[i]} -> `; 132 const neighbors = this.adjList.get(this.vertices[i]); 133 for (let j = 0; j < neighbors.length; j++) { 134 s +=`${neighbors[j]} `; 135 } 136 s += '\n'; 137 } 138 return s; 139 } 140 141 } 142 143 144 const graph = new Graph(); 145 const myVertices = ['A','B','C','D','E','F','G','H','I']; 146 for (let i = 0; i < myVertices.length; i++) { 147 graph.addVertex(myVertices[i]); 148 } 149 graph.addEdge('A','B'); 150 graph.addEdge('A','C'); 151 graph.addEdge('A', 'D'); 152 graph.addEdge('C', 'D'); 153 graph.addEdge('C', 'G'); 154 graph.addEdge('D', 'G'); 155 graph.addEdge('D', 'H'); 156 graph.addEdge('B', 'E'); 157 graph.addEdge('B', 'F'); 158 graph.addEdge('E', 'I'); 159 console.log(graph.toString());
二、简单应用
1、图的遍历
1.1 广度优先搜索
概念:广度优先搜索算法会从指定的第一个顶点开始遍历图,先访问其所有的邻点(相邻顶点),就像一次访问图的一层(先宽后深地访问顶点)。
1.2 深度优先搜索