1、编写一个函数让用户输入这张图,用邻接表存储。 2、编写函数实现此图的深度优先搜索遍历。 3、编程实现循环队列,编写初始化、创建、入队、出队等算法。 4、利用循环队列对图1实现广度优先搜索遍历。 要求: 1、
时间: 2023-07-10 18:39:48 浏览: 43
非常抱歉,我是一个语言模型AI,无法直接执行编程任务。但我可以为您提供相关的代码示例和解释。
1、邻接表存储图:
邻接表是一种表示图的数据结构,它将每个顶点的所有邻接点存储为一个链表。下面是邻接表存储图的代码示例:
```
#include <stdio.h>
#include <stdlib.h>
#define MAXVEX 100 // 最大顶点数
// 边表节点结构体
typedef struct EdgeNode {
int adjvex; // 邻接点域,存储该顶点对应的下标
int weight; // 权值
struct EdgeNode *next; // 链域,指向下一个邻接点
} EdgeNode;
// 顶点表结构体
typedef struct VertexNode {
int data; // 顶点域,存储顶点信息
EdgeNode *firstedge; // 边表头指针
} VertexNode, AdjList[MAXVEX];
// 图结构体
typedef struct {
AdjList adjList; // 邻接表
int numVertexes; // 图中当前顶点数
int numEdges; // 图中当前边数
} GraphAdjList;
// 建立无向图的邻接表结构
void CreateALGraph(GraphAdjList *G) {
int i, j, k;
EdgeNode *e;
printf("请输入顶点数和边数:");
scanf("%d %d", &G->numVertexes, &G->numEdges);
// 读入顶点信息,建立顶点表
for (i = 0; i < G->numVertexes; i++) {
printf("请输入第%d个顶点的值:", i + 1);
scanf("%d", &G->adjList[i].data);
G->adjList[i].firstedge = NULL;
}
// 建立边表
for (k = 0; k < G->numEdges; k++) {
printf("请输入边(vi, vj)上的顶点序号:");
scanf("%d %d", &i, &j);
// 头插法插入边表节点
e = (EdgeNode *) malloc(sizeof(EdgeNode));
e->adjvex = j;
e->next = G->adjList[i].firstedge;
G->adjList[i].firstedge = e;
e = (EdgeNode *) malloc(sizeof(EdgeNode));
e->adjvex = i;
e->next = G->adjList[j].firstedge;
G->adjList[j].firstedge = e;
}
}
```
2、深度优先搜索遍历:
深度优先搜索(Depth-First Search,DFS)是一种用于遍历或搜索树或图的算法。它沿着树的深度遍历树的节点,尽可能深地搜索树的分支。下面是深度优先搜索遍历的代码示例:
```
#define MAXVEX 100 // 最大顶点数
int visited[MAXVEX]; // 访问标志数组
// 邻接表存储图的深度优先遍历递归算法
void DFS(GraphAdjList G, int i) {
EdgeNode *p;
visited[i] = 1;
printf("%d ", G.adjList[i].data);
p = G.adjList[i].firstedge;
while (p) {
if (!visited[p->adjvex]) {
DFS(G, p->adjvex);
}
p = p->next;
}
}
// 邻接表存储的图的深度遍历操作
void DFSTraverse(GraphAdjList G) {
int i;
// 初始化所有顶点为未访问状态
for (i = 0; i < G.numVertexes; i++) {
visited[i] = 0;
}
// 对每个未访问过的顶点调用DFS
for (i = 0; i < G.numVertexes; i++) {
if (!visited[i]) {
DFS(G, i);
}
}
}
```
3、循环队列:
循环队列是一种队列的实现方式,它使用循环数组实现,可以避免数组元素的前移操作,从而提高队列的效率。下面是循环队列的初始化、创建、入队、出队算法的代码示例:
```
#define MAXSIZE 100 // 循环队列的最大长度
typedef struct {
int data[MAXSIZE]; // 存储队列元素
int front; // 队头指针
int rear; // 队尾指针
} SqQueue;
// 初始化循环队列
void InitQueue(SqQueue *Q) {
Q->front = 0;
Q->rear = 0;
}
// 循环队列入队操作
int EnQueue(SqQueue *Q, int x) {
if ((Q->rear + 1) % MAXSIZE == Q->front) { // 队列已满
return 0;
}
Q->data[Q->rear] = x;
Q->rear = (Q->rear + 1) % MAXSIZE; // 队尾指针后移一位,若到最后则转到数组头部
return 1;
}
// 循环队列出队操作
int DeQueue(SqQueue *Q, int *x) {
if (Q->front == Q->rear) { // 队列为空
return 0;
}
*x = Q->data[Q->front];
Q->front = (Q->front + 1) % MAXSIZE; // 队头指针后移一位,若到最后则转到数组头部
return 1;
}
```
4、广度优先搜索遍历:
广度优先搜索(Breadth-First Search,BFS)是一种用于遍历或搜索树或图的算法。它从根节点开始,沿着树的宽度遍历树的节点,直到找到目标节点或遍历完整个树。下面是广度优先搜索遍历的代码示例:
```
void BFSTraverse(GraphAdjList G) {
int i, j;
SqQueue Q;
EdgeNode *p;
// 初始化所有顶点为未访问状态
for (i = 0; i < G.numVertexes; i++) {
visited[i] = 0;
}
InitQueue(&Q);
// 对每个未访问过的顶点进行广度优先遍历
for (i = 0; i < G.numVertexes; i++) {
if (!visited[i]) {
visited[i] = 1;
printf("%d ", G.adjList[i].data);
EnQueue(&Q, i);
while (Q.front != Q.rear) {
DeQueue(&Q, &j);
p = G.adjList[j].firstedge;
while (p) {
if (!visited[p->adjvex]) {
visited[p->adjvex] = 1;
printf("%d ", G.adjList[p->adjvex].data);
EnQueue(&Q, p->adjvex);
}
p = p->next;
}
}
}
}
}
```