#DEV C++,正确安装了EGE图形库,但是这个代码中我输入了起始节点终止节点与权重后,输出的深度优先结果与EGE图库标注的顺序不符,例如:我输入的起点终点权重是:0 1 1
0 2 1
1 3 1
1 4 1
2 5 1
2 6 1
3 7 1
5 8 1
后输出的深度优先搜索结果是01374256,而EGE图库标注(蓝色)亮起的顺序是02561437,这是为什么?
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <graphics.h>
#include <math.h>
#include <conio.h>
#define MAX_VERTICES 100
#include <windows.h>
// 邻接表结构
typedef struct Node {
int vertex;
int weight;
struct Node* next;
} Node;
typedef struct {
int numVertices;
Node** adjacencyList;
} Graph;
// 创建图
Graph* createGraph(int numVertices) {
Graph* graph = (Graph*)malloc(sizeof(Graph));
graph->numVertices = numVertices;
graph->adjacencyList = (Node**)malloc(numVertices * sizeof(Node*));
for (int i = 0; i < numVertices; i++) {
graph->adjacencyList[i] = NULL;
}
return graph;
}
// 添加边
void addEdge(Graph* graph, int startVertex, int endVertex, int weight) {
Node* newNode = (Node*)malloc(sizeof(Node));
newNode->vertex = endVertex;
newNode->weight = weight;
newNode->next = NULL;
// 如果链表为空,直接插入
if (graph->adjacencyList[startVertex] == NULL) {
graph->adjacencyList[startVertex] = newNode;
} else {
// 否则按顺序插入
Node* currentNode = graph->adjacencyList[startVertex];
Node* prevNode = NULL;
while (currentNode != NULL && currentNode->vertex < endVertex) {
prevNode = currentNode;
currentNode = currentNode->next;
}
if (prevNode == NULL) {
newNode->next = graph->adjacencyList[startVertex];
graph->adjacencyList[startVertex] = newNode;
} else {
newNode->next = prevNode->next;
prevNode->next = newNode;
}
}
}
// 打印图的结构
void printGraph(Graph* graph) {
printf("图的结构:\n");
for (int i = 0; i < graph->numVertices; i++) {
Node* currentNode = graph->adjacencyList[i];
printf("顶点 %d:", i);
while (currentNode != NULL) {
printf("(%d, %d) ", currentNode->vertex, currentNode->weight);
currentNode = currentNode->next;
}
printf("\n");
}
}
// 广度优先搜索
void breadthFirstSearch(Graph* graph, int startVertex) {
int* visited = (int*)malloc(graph->numVertices * sizeof(int));
int* queue = (int*)malloc(graph->numVertices * sizeof(int));
int front = 0, rear = 0;
for (int i = 0; i < graph->numVertices; i++) {
visited[i] = 0;
}
visited[startVertex] = 1;
queue[rear++] = startVertex;
printf("广度优先搜索结果:");
while (front < rear) {
int currentVertex = queue[front++];
printf("%d ", currentVertex);
Node* currentNode = graph->adjacencyList[currentVertex];
while (currentNode != NULL) {
if (visited[currentNode->vertex] == 0) {
visited[currentNode->vertex] = 1;
queue[rear++] = currentNode->vertex;
}
currentNode = currentNode->next;
}
}
printf("\n");
free(visited);
free(queue);
}
// 深度优先搜索
void depthFirstSearchUtil(Graph* graph, int startVertex, int* visited, int* dfsOrder, int* dfsIndex) {
visited[startVertex] = 1;
dfsOrder[(*dfsIndex)++] = startVertex;
Node* currentNode = graph->adjacencyList[startVertex];
while (currentNode != NULL) {
if (visited[currentNode->vertex] == 0) {
depthFirstSearchUtil(graph, currentNode->vertex, visited, dfsOrder, dfsIndex);
}
currentNode = currentNode->next;
}
}
void depthFirstSearch(Graph* graph, int startVertex) {
int* visited = (int*)malloc(graph->numVertices * sizeof(int));
int* dfsOrder = (int*)malloc(graph->numVertices * sizeof(int));
int dfsIndex = 0;
for (int i = 0; i < graph->numVertices; i++) {
visited[i] = 0;
}
depthFirstSearchUtil(graph, startVertex, visited, dfsOrder, &dfsIndex);
printf("深度优先搜索结果:");
for (int i = 0; i < dfsIndex; i++) {
printf("%d ", dfsOrder[i]);
}
printf("\n");
free(visited);
free(dfsOrder);
}
int main() {
int numVertices;
printf("请输入图的顶点个数:");
scanf("%d", &numVertices);
Graph* graph = createGraph(numVertices);
printf("请输入带权边的起始顶点、结束顶点和权重:\n");
printf("(输入-1 -1 -1结束)\n");
while (true) {
int startVertex, endVertex, weight;
scanf("%d %d %d", &startVertex, &endVertex, &weight);
if (startVertex == -1 && endVertex == -1 && weight == -1) {
break;
}
addEdge(graph, startVertex, endVertex, weight);
}
printGraph(graph);
breadthFirstSearch(graph, 0);
depthFirstSearch(graph, 0);
// 使用EGE图库绘制图形并标注搜索顺序
initgraph(640, 480);
setbkcolor(BLACK);
cleardevice();
int radius = 100;
int centerX = 320;
int centerY = 240;
int startAngle = 0;
int endAngle = 360;
// 绘制顶点
for (int i = 0; i < graph->numVertices; i++) {
int x = centerX + radius * cos(i * 2 * M_PI / graph->numVertices);
int y = centerY + radius * sin(i * 2 * M_PI / graph->numVertices);
circle(x, y, 30);
char vertexLabel[2];
sprintf(vertexLabel, "%d", i);
outtextxy(x - 5, y - 5, vertexLabel);
}
// 标注广度优先搜索顺序
int* bfsOrder = (int*)malloc(graph->numVertices * sizeof(int));
int bfsIndex = 0;
int* visited = (int*)malloc(graph->numVertices * sizeof(int));
for (int i = 0; i < graph->numVertices; i++) {
visited[i] = 0;
}
int* queue = (int*)malloc(graph->numVertices * sizeof(int));
int front = 0, rear = 0;
visited[0] = 1;
queue[rear++] = 0;
while (front < rear) {
int currentVertex = queue[front++];
bfsOrder[bfsIndex++] = currentVertex;
Node* currentNode = graph->adjacencyList[currentVertex];
while (currentNode != NULL) {
if (visited[currentNode->vertex] == 0) {
visited[currentNode->vertex] = 1;
queue[rear++] = currentNode->vertex;
}
currentNode = currentNode->next;
}
}
// 绘制广度优先搜索顺序
for (int i = 0; i < bfsIndex; i++) {
int x = centerX + radius * cos(bfsOrder[i] * 2 * M_PI / graph->numVertices);
int y = centerY + radius * sin(bfsOrder[i] * 2 * M_PI / graph->numVertices);
setcolor(RED);
circle(x, y, 30);
Sleep(500);
}
// 标注深度优先搜索顺序
int* dfsOrder = (int*)malloc(graph->numVertices * sizeof(int));
int dfsIndex = 0;
for (int i = 0; i < graph->numVertices; i++) {
visited[i] = 0;
}
int* stack = (int*)malloc(graph->numVertices * sizeof(int));
int top = -1;
stack[++top] = 0;
while (top >= 0) {
int currentVertex = stack[top--];
if (visited[currentVertex] == 0) {
visited[currentVertex] = 1;
dfsOrder[dfsIndex++] = currentVertex;
Node* currentNode = graph->adjacencyList[currentVertex];
while (currentNode != NULL) {
if (visited[currentNode->vertex] == 0) {
stack[++top] = currentNode->vertex;
}
currentNode = currentNode->next;
}
}
}
// 绘制深度优先搜索顺序
for (int i = 0; i < dfsIndex; i++) {
int x = centerX + radius * cos(dfsOrder[i] * 2 * M_PI / graph->numVertices);
int y = centerY + radius * sin(dfsOrder[i] * 2 * M_PI / graph->numVertices);
setcolor(BLUE);
circle(x, y, 30);
Sleep(500);
}
getch();
closegraph();
free(bfsOrder);
free(dfsOrder);
free(visited);
free(queue);
free(stack);
return 0;
}
以下答案参考newbing,回答由博主波罗歌编写:
问题出现的原因是深度优先搜索的递归调用顺序与EGE图库绘制顺序不同导致的。在深度优先搜索中,我们是根据邻接表的顺序进行递归调用的,而在EGE图库中,我们是按照顶点的顺序进行绘制的。因此,当顶点的邻接表中的顶点的顺序与它们在图中的顺序不一致时,深度优先搜索的结果与EGE图库绘制顺序不一致。
要解决这个问题,需要修改广度优先搜索和深度优先搜索的实现,以便按照EGE图库的顺序进行搜索。具体实现如下:
void breadthFirstSearch(Graph* graph, int startVertex, int* bfsOrder) {
int* visited = (int*)malloc(graph->numVertices * sizeof(int));
int* queue = (int*)malloc(graph->numVertices * sizeof(int));
int front = 0, rear = 0;
for (int i = 0; i < graph->numVertices; i++) {
visited[i] = 0;
}
visited[startVertex] = 1;
queue[rear++] = startVertex;
int index = 0;
while (front < rear) {
int currentVertex = queue[front++];
bfsOrder[index++] = currentVertex;
Node* currentNode = graph->adjacencyList[currentVertex];
while (currentNode != NULL) {
if (visited[currentNode->vertex] == 0) {
visited[currentNode->vertex] = 1;
queue[rear++] = currentNode->vertex;
}
currentNode = currentNode->next;
}
}
free(visited);
free(queue);
}
void depthFirstSearchUtil(Graph* graph, int startVertex, int* visited, int* dfsOrder, int* dfsIndex) {
visited[startVertex] = 1;
dfsOrder[(*dfsIndex)++] = startVertex;
Node* currentNode = graph->adjacencyList[startVertex];
while (currentNode != NULL) {
if (visited[currentNode->vertex] == 0) {
depthFirstSearchUtil(graph, currentNode->vertex, visited, dfsOrder, dfsIndex);
}
currentNode = currentNode->next;
}
}
void depthFirstSearch(Graph* graph, int startVertex, int* dfsOrder) {
int* visited = (int*)malloc(graph->numVertices * sizeof(int));
int dfsIndex = 0;
for (int i = 0; i < graph->numVertices; i++) {
visited[i] = 0;
}
depthFirstSearchUtil(graph, startVertex, visited, dfsOrder, &dfsIndex);
free(visited);
}
int main() {
// ...
// 广度优先搜索
int* bfsOrder = (int*)malloc(graph->numVertices * sizeof(int));
breadthFirstSearch(graph, 0, bfsOrder);
// 绘制广度优先搜索顺序
for (int i = 0; i < graph->numVertices; i++) {
int x = centerX + radius * cos(bfsOrder[i] * 2 * M_PI / graph->numVertices);
int y = centerY + radius * sin(bfsOrder[i] * 2 * M_PI / graph->numVertices);
setcolor(RED);
circle(x, y, 30);
Sleep(500);
}
// 深度优先搜索
int* dfsOrder = (int*)malloc(graph->numVertices * sizeof(int));
depthFirstSearch(graph, 0, dfsOrder);
// 绘制深度优先搜索顺序
for (int i = 0; i < graph->numVertices; i++) {
int x = centerX + radius * cos(dfsOrder[i] * 2 * M_PI / graph->numVertices);
int y = centerY + radius * sin(dfsOrder[i] * 2 * M_PI / graph->numVertices);
setcolor(BLUE);
circle(x, y, 30);
Sleep(500);
}
// ...
return 0;
}
这样,广度优先搜索和深度优先搜索的结果将按照EGE图库的顺序进行搜索和绘制,解决了顶点标注顺序与EGE图库绘制顺序不一致的问题。
希望这个解答对你有帮助!如果还有其他问题,请随时提问。
如果我的回答解决了您的问题,请采纳!
代码和EGE图形库在表示深度优先搜索(DFS)的 "顺序" 上存在差异,主要在遍历相邻节点时所采用的顺序不同。
你的代码中用的是邻接表来存储图的信息,每次添加一条边时,都会将其插入到邻接表中的适当位置,以保证每个顶点的邻接列表按照顶点的值升序排列。因当进行深度优先搜索时,你会先遍历数值较小的顶点。
EGE图形库在显示图形并进行DFS遍历时,可能并未按照顶点的数值进行排序,而是按照你添加边的顺序来遍历。这是你看到的DFS遍历顺序与代码输出不符的原因。
如果希望你的代码输出的DFS顺序与EGE图形库的可视化结果一致,那么你可能要调整你的代码,使得它在进行DFS遍历时按照你添加边的顺序,而不是顶点的数值来遍历相邻的顶点。具体来说,你可以在添加边的时候,总是将新的边添加到邻接列表的末尾,而不是按照顶点的值插入到适当的位置。
这里是修改后的addEdge
函数:
// 添加边
void addEdge(Graph* graph, int startVertex, int endVertex, int weight) {
Node* newNode = (Node*)malloc(sizeof(Node));
newNode->vertex = endVertex;
newNode->weight = weight;
newNode->next = NULL;
// 如果链表为空,直接插入
if (graph->adjacencyList[startVertex] == NULL) {
graph->adjacencyList[startVertex] = newNode;
} else {
// 否则插入到链表的末尾
Node* currentNode = graph->adjacencyList[startVertex];
while (currentNode->next != NULL) {
currentNode = currentNode->next;
}
currentNode->next = newNode;
}
}
在使用DEV C++中的EGE图库进行深度优先搜索时,输出的顶点顺序与EGE图库标注的顺序不符的问题可能是由于以下原因导致的:
图的存储方式:深度优先搜索算法的顺序依赖于图的存储方式。如果图以邻接矩阵或邻接表的形式存储,可能会导致顶点的访问顺序不同。请确保你的代码和EGE图库使用相同的图存储方式。
算法实现:你使用的深度优先搜索算法的实现可能与EGE图库中的实现有所不同。确保你的深度优先搜索算法是正确的,并按照预期的顺序访问和标注顶点。
要解决这个问题,你可以尝试以下方法:
检查图的存储方式:确保你的代码和EGE图库使用相同的图存储方式,比如邻接矩阵或邻接表。
检查深度优先搜索算法的实现:仔细检查你的深度优先搜索算法的实现是否正确。确保你按照深度优先的原则访问和标注顶点,即先访问一个节点的所有邻居节点,再递归地访问邻居节点的邻居节点。
对比结果:将你的代码输出的深度优先搜索结果与EGE图库标注的顺序进行对比。检查是否有任何错误或缺失的节点。如果有差异,试着找到造成差异的具体原因并进行调试。
最后,需要注意的是,深度优先搜索在不同的图中可能会产生不同的顶点访问顺序。这是由于图的结构以及算法的实现方式所决定的。因此,得到不同的顶点访问顺序并不一定是错误的,只要算法的实现是正确的,结果也是有效的。
C/C++语言:图的遍历之深度优先搜索 代码实现
//
// Created by dong on 2022-03-16.
//
#include "home10.h"
int main(){
AMGraph G;
G.vernum = 8;//8个顶点
G.arcnum = 9;
//
char test[8]={'a','b','c','d','e','f','g','h'};
for(int i = 0; i < 8; i++)
G.vertexs[i] = test[i];
//
int a[8][8]={0,1,1,0,0,0,0,0,
1,0,0,1,1,0,0,0,
1,0,0,0,0,1,1,0,
0,1,0,0,0,0,0,1,
0,1,0,0,0,0,0,1,
0,0,1,0,0,0,1,0,
0,0,1,0,0,1,0,0,
0,0,0,1,1,0,0,0};
for(int i = 0; i < 8; i++)
for(int j = 0; j < 8; j++)
G.arcs[i][j] = a[i][j];
//
Function(G,'a');
return 0;
}
仔细检查您的输入与EGE图库的表示方式是否一致,确保输入的节点编号、边权重等与图库中的表示方式相同。
检查您的DFS算法的实现方式是否与EGE图库中的实现方式相同。您以尝试使用不同的DFS算法实现,例如非递归的深度优先搜索,以查看结果是否一致。