javascript数据结构与算法——图和字典
由于js中封装的字典数据类型比较简单,并且在图中也能用到,所以在这里也对字典进行封装。
一、字典封装
字典中的方法:
添加->set()
判断->has()
删除->remove()
获取->get()
获取全部的key->getKeys()
获取全部的value->getValues()
长度->size()
清空->clear()
对字典封装代码:
<script>
function Dictionary() {
// 设置字典属性
this.items = {};
// 设置字典的方法
// 设置字典的方法
Dictionary.prototype.set = function (key, value) {
this.items[key] = value;
}
// 判断字典是否存在某一个key
Dictionary.prototype.has = function (key) {
return this.items.hasOwnProperty(key);
}
// 从字典中删除某一个元素
Dictionary.prototype.remove = function (key) {
if (!this.has(key)) return false;
delete this.items[key];
return true;
}
// 获取value值
Dictionary.prototype.get = function (key) {
return this.has(key) ? this.items[key] : undefined;
}
// 获取全部的key
Dictionary.prototype.getKeys = function(){
return Object.keys(this.items);
}
// 获取全部的value
Dictionary.prototype.getValues = function(){
return Object.values(this.items);
}
// 获取长度size
Dictionary.prototype.size = function(){
return this.getKeys().length;
}
// 清空字典
Dictionary.prototype.clear = function(){
this.items = {};
}
}
</script>
下面封装图:
图中的定义比较多,所以这里就不一一列举,主要是举出一些比较常见的方法和属性
属性:①顶点 ②边
方法:
1、添加顶点->addVert
2、添加边->addEdge
3、打印出图结构->toString
4、图的遍历
4.1广度优先遍历->bfs
4.2深度优先遍历->dfs
图的边
可以使用邻接表大致如图所示
可以使用邻接矩阵
这里我们使用字典类型来存储边与边的关系
4.1广度优先遍历(BFS)
按照如下顺序来进行遍历
实现思路: 设置三色原则,未访问过的节点设置为white,访问的节点但是其子节点没有访问完,设置为gray,完全访问完使用black颜色。使用队列的先进先出的原则,当访问到哪个节点得时候,将其子节点全部压入队列中,然后逐个取出访问。
4.2深度优先遍历(DFS)
实现思路:这里使用深度优先遍历,设置三色原则,未访问过的节点设置为white,访问的节点但是其子节点没有访问完,设置为gray,完全访问完使用black颜色。这里使用递归遍历即可实现
图的相关代码如下:
一、队列代码
<script>
function Quene() {
// 1、构造初始化变量
this.items = [];
}
// 1、设置加入元素
Quene.prototype.enQuene = function (element) {
this.items.push(element);
}
// 2、设置删除元素
Quene.prototype.deQuene = function () {
return this.items.shift();
}
// 3、设置查找第一个元素
Quene.prototype.front = function () {
return this.items[0];
}
// 4、查看队列长度
Quene.prototype.size = function () {
return this.items.length;
}
// 5、查看队列是否为空
Quene.prototype.isEmpty = function () {
return Boolean(this.items.length);
}
// 6、将队列设置成数组
Quene.prototype.toString = function () {
let result = " ";
for (let i = 0; i < this.items.length; i++) {
result += this.items[i] + " ";
}
return result;
}
</script>
图的实现
<script>
let dict = require("./08.字典的实现");
let Dictionary = dict.Dictionary;
let quene = require("./09.队列实现");
let Quene = quene.Quene;
// 图的封装
function Graph() {
// 图的属性
// 图的顶点
this.vert = [];
// 图的边
this.edges = new Dictionary();
// 图的方法
// 1、添加顶点
Graph.prototype.addVert = function (v) {
this.vert.push(v);
this.edges.set(v, []);
}
// 2、添加边
Graph.prototype.addEdge = function (a, b) {
this.edges.get(a).push(b);
this.edges.get(b).push(a);
}
// 3、打印出图结构
Graph.prototype.toString = function () {
let result = "";
for (let i = 0; i < this.vert.length; i++) {
result += this.vert[i] + " ——> "
let Vedge = this.edges.get(this.vert[i]);
for(let j = 0;j<Vedge.length;j++){
result += Vedge[j] + " ";
}
result += "\n";
}
return result;
}
// 4、图的遍历
Graph.prototype.initColors = function(){
let colors = [];
for(let i = 0;i<this.vert.length;i++){
colors[this.vert[i]] = "white";
}
return colors;
}
// 4.1广度优先遍历
Graph.prototype.bfs = function(v,handler){
// 1、进行初始化设置
// 1.1设置颜色
let colors = this.initColors();
// 1.2初始化队列
let quene_1 = new Quene();
// 2、将传入的节点插入到队列中
quene_1.enQuene(v);
while(quene_1.size()!==0){
let e = quene_1.deQuene();
// 更改颜色
colors[e] = "grap";
let Vedges = this.edges.get(e);
for(let k =0;k < Vedges.length;k++){
// 如果节点的颜色是白色,说明没有遍历过
if(colors[Vedges[k]] == "white"){
quene_1.enQuene(Vedges[k]);
colors[Vedges[k]] = "gray";
}
}
handler(e);
colors[e] = "black";
}
}
// 4.2深度优先遍历
Graph.prototype.dfs = function(v,handler){
// 1、初始化颜色设置
let colors = this.initColors();
this.dfsVirst(v,colors,handler);
}
Graph.prototype.dfsVirst = function(v,colors,handler){
// 处理节点
handler(v);
// 设置节点颜色
colors[v] = "gray";
let vedges = this.edges.get(v);
for(let i =0 ;i<vedges.length;i++){
if(colors[vedges[i]] == "white"){
this.dfsVirst(vedges[i],colors,handler);
}
}
colors[v] = "black";
}
}
let graph = new Graph();
let arr = ['A', "B", "C", "D", "E", "F", "G", "H", "I"];
for (let i = 0; i < arr.length; i++) {
graph.addVert(arr[i]);
}
graph.addEdge('A', 'B');
graph.addEdge('A', 'C');
graph.addEdge('A', 'D');
graph.addEdge('B', 'E');
graph.addEdge('B', 'F');
graph.addEdge('C', 'D');
graph.addEdge('C', 'G');
graph.addEdge('D', 'G');
graph.addEdge('D', 'H');
graph.addEdge('E', 'I');
let result = "";
graph.bfs(graph.vert[0],function(v){
result += v + " ";
})
console.log(result);
result = "" ;
graph.dfs(graph.vert[0],function(v){
result += v + " ";
})
console.log(result);
</script>