问题描述
(1)基于邻接表存储结构实现图的基本操作,并在main主函数中来实现图中边/弧的插入操作。
①建立图;
②图的深度优先遍历;
③图的广度优先遍历
④图中边/弧的插入。
问题描述:
①从键盘输入顶点数及边/弧数并输入顶点信息、边/弧的顶点起始编号和终止编号;要求:图采用链式存储。
②分别调用深度优先搜索遍历或者广度优先遍历算法对建立好的图进行遍历。要求分别显示遍历后的结点序列。
③根据输入要插入边/弧的顶点起始编号和终止编号,将其插入到图中,并在屏幕中以两种遍历中的一种将结点序列进行显示或者以链接表形式输出。
程序清单:
(1)【广度与深度和插入一体】
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
using namespace std;
#define MAX_VERTEX_NUM 20
typedef int VertexType;//深度用
typedef int ElemType;//链队用
typedef enum { DG, DN, UDG, UDN }GraphKind;
//枚举变量
typedef struct QNode {
ElemType data;
struct QNode* next;
}QNode, * QueuePtr;
typedef struct {
QueuePtr front;
QueuePtr rear;
}LinkQueue;
int visited[MAX_VERTEX_NUM];
typedef struct ArcNode
//表结点结构体
{
int adjvex;
struct ArcNode* nextarc;
}ArcNode;
typedef struct VNode
//表头结点
{
VertexType data;
ArcNode* firstarc;
}VNode, AdjList[MAX_VERTEX_NUM];
typedef struct
//定义图
{
AdjList vertices;
int vexnum, arcnum;
//vex定点 arc边
GraphKind Kind;
}ALGraph;
ALGraph Create_Graph()
//初始化建立
{
ArcNode* p;
int i, s, d;
ALGraph adjg;
adjg.Kind = DG;
cout << "请输入顶点数和边数:";
cin >> s >> d;
adjg.vexnum = s;//定点
adjg.arcnum = d;//边
for (i = 0; i < adjg.vexnum; i++)
{
cout << "第" << i + 1 << "个顶点信息:";
cin >> adjg.vertices[i].data;
adjg.vertices[i].firstarc = NULL;
}
for (i = 0; i < adjg.arcnum; i++)
{
cout << "第" << i + 1 << "条边的起始顶点编号和终止顶点编号:";
cin >> s >> d;
while (s<1 || s>adjg.vexnum || d<1 || d>adjg.vexnum)
{
cout << "编号超出范围,重新输入:";
cin >> s >> d;
}
s--;
d--;
p = (ArcNode*)malloc(sizeof(ArcNode));
//分配内存空间
p->adjvex = d;
p->nextarc = adjg.vertices[s].firstarc;
adjg.vertices[s].firstarc = p;
}
return adjg;
}
void DFS(ALGraph G, int v)
//深度优先
{
ArcNode* p;
visited[v - 1] = 1;
v--;
cout << G.vertices[v].data;
p = G.vertices[v].firstarc;
while (p)
{
int j = p->adjvex;
if (visited[j] == 0)
DFS(G, j + 1);
p = p->nextarc;
}
}
void DFS_straverse_Grapg(ALGraph G)
//全图
{
int v;
for (v = 0; v < G.vexnum; v++)
visited[v] = 0;
for (v = 0; v < G.vexnum; v++)
if (!visited[v])
DFS(G, v + 1);
}
void insertion(ALGraph& adjg)
//插入边
{
ArcNode* p;
int s, d;
cout << "请输入要插入的边的起始顶点编号和终止顶点编号:";
cin >> s >> d;
while (s<1 || s>adjg.vexnum || d<1 || d>adjg.vexnum)
{
cout << "编号超出范围,重新输入:";
cin >> s >> d;
}
s--;
d--;
p = (ArcNode*)malloc(sizeof(ArcNode));
p->adjvex = d;
p->nextarc = adjg.vertices[s].firstarc;
adjg.vertices[s].firstarc = p;
}
/// <链队列>
bool InitQueue(LinkQueue& Q)
//初始化链队列
{
Q.front = Q.rear = new QNode;//头节点
if (!Q.front || !Q.rear)return 0;
Q.front->next = NULL;
return 1;
}
bool EnQueue(LinkQueue& Q, ElemType e)
//元素入队
{
QueuePtr temp = new QNode;
if (!temp)return 0;
temp->data = e;
temp->next = NULL;
Q.rear->next = temp;
Q.rear = temp;
return 1;
}
bool DeQueue(LinkQueue& Q, ElemType& e)
//出队
{
if (Q.front == Q.rear)
return 0;
QueuePtr temp = Q.front->next;//指向第一个结点的指针
e = temp->data;
Q.front->next = temp->next;
if (Q.rear == temp)//若出队的是尾指针指向结点,则需要调整尾指针,否则删除后尾指针指向空
Q.rear = Q.front;
delete temp;
return 1;
}
bool DestroyQueue(LinkQueue& Q)
//销毁队列
{
QueuePtr temp = Q.front;
while (Q.front) {
Q.front = Q.front->next;
delete temp;
temp = Q.front;
}
return 1;
}
bool QueueEmpty(LinkQueue Q)
{
if (Q.front == Q.rear)
return 1;
else
return 0;
}
void BFS_traverse(ALGraph G, int vi)
//广度遍历
{
int visited[MAX_VERTEX_NUM];
int i, v;
ArcNode* p;
LinkQueue Q;
InitQueue(Q);
for (i = 0; i < G.vexnum; i++)
visited[i] = 0;
visited[vi - 1] = 1;
cout << G.vertices[vi - 1].data;
EnQueue(Q, vi);
while (!QueueEmpty(Q))
{
DeQueue(Q, v);
v--;
p = G.vertices[v].firstarc;
while (p != NULL)
{
int j = p->adjvex;
if (visited[j] == 0)
{
visited[j] = 1;
cout<< G.vertices[j].data;
EnQueue(Q, j + 1);
}
p = p->nextarc;
}
}
}
int main()
{
ALGraph g;
g = Create_Graph();
//初始化 建表
cout << "DFS:" << endl;//深度
DFS_straverse_Grapg(g);
//顶点遍历
cout << endl;//间隔
cout << "BFS:" << endl;//广度
BFS_traverse(g, 1);
cout << endl;//间隔
insertion(g);
//插入一个边
cout << " DFS_straverse_Grapg:" << endl;//深度
DFS_straverse_Grapg(g);
//遍历全图
cout << endl;
cout << "BFS:" << endl;//广度
BFS_traverse(g, 1);
return 0;
}