给定一个无向图和一个图顶点,编程输出该图删除给定顶点前后按深度优先遍历及广度优先遍历方式遍历的图顶点序列。 给定的无向图和图顶点满足以下要求: 1、无向图的顶点个数n大于等于3,小于等于100,输入时顶点编号用整数0~n-1表示; 2、无向图在删除给定顶点前后都是连通的; 3、无论何种遍历,都是从编号为0的顶点开始遍历,访问相邻顶点时按照编号从小到大的顺序访问; 4、删除的顶点编号不为0。C语言
时间: 2024-02-06 07:11:57 浏览: 123
以下是一个基于邻接表的深度优先遍历和广度优先遍历的实现,其中删除指定节点的部分使用了类似于链表的删除方式。
```c
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define MAX_VERTICES 100
// 邻接表节点
typedef struct AdjListNode {
int dest;
struct AdjListNode* next;
} AdjListNode;
// 邻接表头节点
typedef struct AdjList {
AdjListNode* head;
} AdjList;
// 图
typedef struct Graph {
int V;
AdjList* array;
} Graph;
// 创建邻接表节点
AdjListNode* newAdjListNode(int dest) {
AdjListNode* newNode = (AdjListNode*) malloc(sizeof(AdjListNode));
newNode->dest = dest;
newNode->next = NULL;
return newNode;
}
// 创建图
Graph* createGraph(int V) {
Graph* graph = (Graph*) malloc(sizeof(Graph));
graph->V = V;
graph->array = (AdjList*) malloc(V * sizeof(AdjList));
for (int i = 0; i < V; i++) {
graph->array[i].head = NULL;
}
return graph;
}
// 添加边
void addEdge(Graph* graph, int src, int dest) {
AdjListNode* newNode = newAdjListNode(dest);
newNode->next = graph->array[src].head;
graph->array[src].head = newNode;
// 无向图需要添加反向边
newNode = newAdjListNode(src);
newNode->next = graph->array[dest].head;
graph->array[dest].head = newNode;
}
// 深度优先遍历
void DFS(Graph* graph, bool visited[], int v) {
visited[v] = true;
printf("%d ", v);
// 遍历所有相邻节点
AdjListNode* node = graph->array[v].head;
while (node != NULL) {
if (!visited[node->dest]) {
DFS(graph, visited, node->dest);
}
node = node->next;
}
}
// 广度优先遍历
void BFS(Graph* graph, bool visited[], int v) {
int queue[MAX_VERTICES];
int front = 0, rear = 0;
visited[v] = true;
queue[rear++] = v;
while (front != rear) {
int vertex = queue[front++];
printf("%d ", vertex);
// 遍历所有相邻节点
AdjListNode* node = graph->array[vertex].head;
while (node != NULL) {
if (!visited[node->dest]) {
visited[node->dest] = true;
queue[rear++] = node->dest;
}
node = node->next;
}
}
}
// 删除指定节点
void deleteVertex(Graph* graph, int v) {
// 删除相邻节点中的该节点
for (int i = 0; i < graph->V; i++) {
AdjListNode* node = graph->array[i].head;
AdjListNode* prev = NULL;
while (node != NULL) {
if (node->dest == v) {
if (prev == NULL) {
graph->array[i].head = node->next;
} else {
prev->next = node->next;
}
free(node);
break;
}
prev = node;
node = node->next;
}
}
// 释放该节点的内存
AdjListNode* head = graph->array[v].head;
while (head != NULL) {
AdjListNode* next = head->next;
free(head);
head = next;
}
graph->array[v].head = NULL;
}
int main() {
int n, v;
scanf("%d %d", &n, &v);
Graph* graph = createGraph(n);
int src, dest;
while (scanf("%d %d", &src, &dest) != EOF) {
addEdge(graph, src, dest);
}
// 输出删除指定节点前的遍历序列
bool* visited = (bool*) calloc(n, sizeof(bool));
DFS(graph, visited, 0);
printf("\n");
BFS(graph, visited, 0);
printf("\n");
// 删除指定节点
deleteVertex(graph, v);
// 输出删除指定节点后的遍历序列
for (int i = 0; i < n; i++) {
visited[i] = false;
}
DFS(graph, visited, 0);
printf("\n");
BFS(graph, visited, 0);
printf("\n");
return 0;
}
```
其中,输入格式为:
```
n v
src1 dest1
src2 dest2
...
```
表示有n个节点,删除节点v,其余边的连接方式为src和dest。
阅读全文