问题描述
在多线程环境中,不同的进程可能需要使用相同的资源。一张 wait-for 图表示有向图中作为节点的不同过程,其中从节点i
到节点j
的一条边表示该节点j
是使用需要节点{i
使用的资源(并且只有在节点j
释放它之后才能使用)。
我们对有向图是否具有任何循环感兴趣。如果是这样,系统可能会进入无法完成任何过程的状态。
我们将用整数0
,....,n - 1
表示过程。我们使用二维列表connections
表示边缘。如果j
在列表connections[i]
中,则表示从过程i
到过程j
的有向边。
编写一个函数返回True
,如果connections
描述了一个有向循环的图,否则返回False
。
示例
- 对于
connections = [[1],[2],[3,4],[4],[0]]
,输出应为findDeadlock(connections) = true
。
此图包含一个循环。
- 对于
connections = [[1,2,3],[2,[3],[]]
,输出应为findDeadlock(connections) = false
。
这是一项任务。
这是我的实现方式
class Node {
constructor(data) {
this.data = data;
this.next = null;
}
}
class LinkedList {
constructor() {
this.head = null;
}
insertAtHead(data) {
let temp = new Node(data);
temp.next = this.head;
this.head = temp;
return this;
}
getHead() {
return this.head;
}
}
class Graph {
constructor(vertices) {
this.vertices = vertices;
this.list = [];
for (let i = 0; i < vertices; i++) {
let temp = new LinkedList();
this.list.push(temp);
}
}
addEdge(source,destination) {
if (source < this.vertices && destination < this.vertices) {
this.list[source].insertAtHead(destination);
}
return this;
}
}
const Colors = {
WHITE: "white",GRAY: "gray",BLACK: "black",};
Object.freeze(Colors);
const isDeadlocked = (g) => {
let color = [];
for (let i = 0; i < g.vertices; i++) {
color[i] = Colors.WHITE;
}
for (let i = 0; i < g.vertices; i++) {
if (color[i] == Colors.WHITE) {
if (detectCycle(g,i,color)) {
console.log(true)
return true;
}
}
}
console.log(false);
return false;
}
const detectCycle = (g,currentVertex,color) => {
color[currentVertex] = Colors.GRAY;
let neighbor;
let nextNode = g.list[currentVertex].getHead();
while (nextNode !== null) {
neighbor = nextNode.data;
if (color[neighbor] == Colors.GRAY) {
return true;
}
if (color[neighbor] == Colors.WHITE && detectCycle(g,neighbor,color)) {
return true;
}
}
color[currentVertex] = Colors.BLACK;
return false;
}
const findDeadlock = (input) => {
const g = new Graph(input.length);
for (let i = 0; i < input.length; i++) {
for (let j = 0; j < input[i].length; j++) {
g.addEdge(i,input[i][j]);
}
}
isDeadlocked(g);
}
const connections = [[1,[]];
findDeadlock(connections);
我的代码第二次测试失败。找不到原因。有帮助吗?
解决方法
至少存在以下两个问题:
(1)输入未正确转换为边。以下代码:
g.addEdge(i,j);
应为:
g.addEdge(i,input[i][j]);
(2)detectCycle
中的循环变量不会为下一次迭代更新。在循环结束之前,您应该包括:
nextNode = nextNode.next;
一般说明::尽管您的LinkedList
实现很好,但在JavaScript中真正实现这种结构却很少有用。您可以使用简单的数组,也可以使用Set
。