问题描述
我想在 Java 中为 long
类型的节点实现 dfs。
我的算法正确计算了节点的数量,以及数量
的边,但不是节点的序列。你能帮我吗
修改我的算法,以便我计算节点的顺序
访问过,正确吗?
这是我的代码:
private int getNumberOfNodes(long firstNode) {
List<Long> marked = new ArrayList<>(); //------------------------------------------->
Stack<Long> stack = new Stack<Long>(); //step 1 Create/declare stack
stack.push(firstNode); //Step 2 Put/push inside the first node
while (!stack.isEmpty()) { //Repeat till stack is empty:
Long node = stack.pop(); //Step 3 Extract the top node in the stack
marked.add(node); //------------------------------------------->
long[] neighbors = xgraph.getNeighborsOf(node); //Get neighbors
if (neighbors.length % 2 == 0) {
} else {
numOfNodesWithOddDegree++;
}
int mnt = 0;
for (long currentNode : neighbors) {
if (!marked.contains(currentNode) && !stack.contains(currentNode) ) { //&& !stack.contains(currentNode)
stack.push(currentNode);
} else {
}
if (!marked.contains(currentNode)) {
numOfEdges++;
}
}
}
return marked.size(); //(int) Arrays.stream(neighbors).count();
}
解决方法
我猜你检查了序列的 marked
列表。
由于您的图是无向图,遍历的顺序可能会根据您首先推入堆栈的邻居而有所不同。这意味着你的函数的逻辑:
xgraph.getNeighborsOf(node)
可能会影响您的序列。请参阅此 wiki https://en.wikipedia.org/wiki/Depth-first_search
中的顶点排序所以我的结论是:你可能有不同的遍历顺序,不代表你的DFS是错的,只要是Deep first search,和给出的答案有一点点不同就可以了。
> ,这是一个实现:
public Result getResults() {
long[] neighbourNodes;
Stack<Long> stack = new Stack<Long>(); //
stack.push(xgraph.firstNode()); //Get first node from graph and push it into stack
while(true) { //While stack is not empty
if (!stack.isEmpty()) {
Long node = stack.pop(); //Pop top element from stack
if(!res.dfsNodeSequence.contains(node)) { //If not explored
neighbourNodes = xgraph.getNeighborsOf(node); //Find the neighbour nodes
/*Sort them in decrementing order using bubble sort */
int length = neighbourNodes.length;
long temp;
for (int i = 0; i < ( length - 1 ); i++) {
for (int j = 0; j < length - i - 1; j++) {
if (neighbourNodes[j] < neighbourNodes[j+1])
{
temp = neighbourNodes[j];
neighbourNodes[j] = neighbourNodes[j+1];
neighbourNodes[j+1] = temp;
}
}
} //sorting completed
for (int idx = 0; idx < neighbourNodes.length; idx++) { //Push any of the neighbour nodes
//that have not been explored/discovered before into the stack
if (!res.dfsNodeSequence .contains(neighbourNodes[idx])) {
stack.push(neighbourNodes[idx]);
res.m = res.m + 1; //Increment number of edges
}
}
if (neighbourNodes.length % 2 != 0) { //Check if the node popped out from the stack has odd or even number of neighbouring nodes
res.numOfNodesWithOddDegree = res.numOfNodesWithOddDegree + 1; //If it has odd number of neighbouring nodes increment the counter
}
res.dfsNodeSequence.add(node); //New node discovered/explored
res.n = res.n + 1; //Increment number of total nodes
}
} else {
break; //Stack is empty so exit infinite while loop
}
}
if (res.numOfNodesWithOddDegree == 0 &&
res.numOfNodesWithOddDegree != 2) { //Check for Euler path
res.graphType = 2;
} else if (res.numOfNodesWithOddDegree == 0 ||
res.numOfNodesWithOddDegree == 2) { //Check for Euler circle
res.graphType = 1;
} else {
res.graphType = 0;
}
return res;
}