请输入总的顶点的数 :(请输入0 - 100的整数)
6
请输入总的边数 :(请输入0 - 100的整数)
6
请输入第 1 个顶点的名字 :v1
请输入第 2 个顶点的名字 :v2
请输入第 3 个顶点的名字 :v3
请输入第 4 个顶点的名字 :v4
请输入第 5 个顶点的名字 :v5
请输入第 6 个顶点的名字 :v6
请输入一条边所依附的第一个顶点 :
v1
请输入一条边所依附的第二个顶点 :
v2
请输入边的权值(整数) :1
请输入一条边所依附的第一个顶点 :
v1
请输入一条边所依附的第二个顶点 :
v3
请输入边的权值(整数) :2
请输入一条边所依附的第一个顶点 :
v1
请输入一条边所依附的第二个顶点 :
v4
请输入边的权值(整数) :3
请输入一条边所依附的第一个顶点 :
v2
请输入一条边所依附的第二个顶点 :
v5
请输入边的权值(整数) :4
请输入一条边所依附的第一个顶点 :
v3
请输入一条边所依附的第二个顶点 :
v5
请输入边的权值(整数) :5
请输入一条边所依附的第一个顶点 :
v4
请输入一条边所依附的第二个顶点 :
v6
请输入边的权值(整数) :6
请输入开始遍历的顶点:2
广度遍历结果 :
v2 v5 v1 v3 v4 v6
请输入总的顶点的数 :(请输入0 - 100的整数)
6
请输入总的边数 :(请输入0 - 100的整数)
6
请输入第 1 个顶点的名字 :v1
请输入第 2 个顶点的名字 :v2
请输入第 3 个顶点的名字 :v3
请输入第 4 个顶点的名字 :v4
请输入第 5 个顶点的名字 :v5
请输入第 6 个顶点的名字 :v6
请输入一条边所依附的第一个顶点 :
v1
请输入一条边所依附的第二个顶点 :
v2
请输入边的权值(整数) :1
请输入一条边所依附的第一个顶点 :
v1
请输入一条边所依附的第二个顶点 :
v3
请输入边的权值(整数) :2
请输入一条边所依附的第一个顶点 :
v1
请输入一条边所依附的第二个顶点 :
v4
请输入边的权值(整数) :3
请输入一条边所依附的第一个顶点 :
v2
请输入一条边所依附的第二个顶点 :
v5
请输入边的权值(整数) :4
请输入一条边所依附的第一个顶点 :
v3
请输入一条边所依附的第二个顶点 :
v5
请输入边的权值(整数) :5
请输入一条边所依附的第一个顶点 :
v4
请输入一条边所依附的第二个顶点 :
v6
请输入边的权值(整数) :6
请输入开始遍历的顶点:2
深度遍历结果 :
v2 v5 v3 v1 v4 v6
深度遍历图结果
请输入总的顶点的数 :(请输入0 - 100的整数)
8
请输入总的边数 :(请输入0 - 100的整数)
8
请输入第 1 个顶点的名字 :v1
请输入第 2 个顶点的名字 :v2
请输入第 3 个顶点的名字 :v3
请输入第 4 个顶点的名字 :v4
请输入第 5 个顶点的名字 :v5
请输入第 6 个顶点的名字 :v6
请输入第 7 个顶点的名字 :v7
请输入第 8 个顶点的名字 :v8
请输入一条边所依附的第一个顶点 :
v1
请输入一条边所依附的第二个顶点 :
v2
请输入边的权值(整数) :1
请输入一条边所依附的第一个顶点 :
v1
请输入一条边所依附的第二个顶点 :
v3
请输入边的权值(整数) :2
请输入一条边所依附的第一个顶点 :
v2
请输入一条边所依附的第二个顶点 :
v4
请输入边的权值(整数) :3
请输入一条边所依附的第一个顶点 :
v2
请输入一条边所依附的第二个顶点 :
v5
请输入边的权值(整数) :4
请输入一条边所依附的第一个顶点 :
v3
请输入一条边所依附的第二个顶点 :
v6
请输入边的权值(整数) :5
请输入一条边所依附的第一个顶点 :
v3
请输入一条边所依附的第二个顶点 :
v7
请输入边的权值(整数) :6
请输入一条边所依附的第一个顶点 :
v4
请输入一条边所依附的第二个顶点 :
v8
请输入边的权值(整数) :7
请输入一条边所依附的第一个顶点 :
v5
请输入一条边所依附的第二个顶点 :
v8
请输入边的权值(整数) :8
请输入开始遍历的顶点:1
深度遍历结果 :
v1 v3 v7 v6 v2 v5 v8 v4
广度遍历图结果
请输入总的顶点的数 :(请输入0 - 100的整数)
8
请输入总的边数 :(请输入0 - 100的整数)
8
请输入第 1 个顶点的名字 :v1
请输入第 2 个顶点的名字 :v2
请输入第 3 个顶点的名字 :v3
请输入第 4 个顶点的名字 :v4
请输入第 5 个顶点的名字 :v5
请输入第 6 个顶点的名字 :v6
请输入第 7 个顶点的名字 :v7
请输入第 8 个顶点的名字 :v8
请输入一条边所依附的第一个顶点 :
v1
请输入一条边所依附的第二个顶点 :
v2
请输入边的权值(整数) :1
请输入一条边所依附的第一个顶点 :
v1
请输入一条边所依附的第二个顶点 :
v3
请输入边的权值(整数) :2
请输入一条边所依附的第一个顶点 :
v2
请输入一条边所依附的第二个顶点 :
v4
请输入边的权值(整数) :3
请输入一条边所依附的第一个顶点 :
v2
请输入一条边所依附的第二个顶点 :
v5
请输入边的权值(整数) :4
请输入一条边所依附的第一个顶点 :
v4
请输入一条边所依附的第二个顶点 :
v8
请输入边的权值(整数) :5
请输入一条边所依附的第一个顶点 :
v5
请输入一条边所依附的第二个顶点 :
v8
请输入边的权值(整数) :6
请输入一条边所依附的第一个顶点 :
v3
请输入一条边所依附的第二个顶点 :
v6
请输入边的权值(整数) :7
请输入一条边所依附的第一个顶点 :
v3
请输入一条边所依附的第二个顶点 :
v7
请输入边的权值(整数) :8
请输入开始遍历的顶点:1
广度遍历结果 :
v1 v3 v2 v7 v6 v5 v4 v8
定义图及其各种操作
#pragma once
#include
#include
using namespace std;
const int MVNum = 100;
//边结点定义
typedef struct ArcNode {
int adjvex; //该边所指向的顶点在表头结点表数组的下标
struct ArcNode* nextarc; //该边指向下一条边的指针
int info; //边的权值
}ArcNode;
//顶点和顶点表的定义
typedef struct VNode {
string data; //顶点的名称
ArcNode* firstarc; //指向第一条依附在该顶点的第一条边
} VNode, AdjList[MVNum]; //定义一个表头结点表的数组类型
//邻接表的定义
typedef struct {
AdjList vertices; //表头结点表
int vexnum, arcnum; //图的顶点数和边数
}ALgraph;
//获取输入结点在表头结点表的数组下标
int LocateVex(ALgraph G, VNode* p) {
for (int i = 0; i <= G.vexnum; i++) {
if (G.vertices[i].data == p->data)
return i;
}
return -1;
}
//构造邻接表表示无向图
/* 需求:
1,表头结点存储图的各个顶点的名字,相应边链表的头结点的指针域
分析:
1,接收键盘录入的总顶点数,总边数
2,for循环,逐个录入图的每一个结点信息(名,指针域初始化未NULL),构造表头结点表
3,for循环,输入 图的各边信息(边的依附顶点),通过依附顶点在表头结点的值获取顶点在表头结点的数组的下标值,
根据获取的下标,生成新的边界点,为结点的各个属性赋值,用链表前插法链入顶点的边链表中
*/
void CreateUDG(ALgraph &G) {
//1,接收键盘录入的总顶点数,总边数
//while (true) {
cout << "请输入总的顶点的数 :(请输入0 - 100的整数)" << endl;
cin >> G.vexnum;
cout << "请输入总的边数 :(请输入0 - 100的整数)" << endl;
cin >> G.arcnum;
//if ((G.vexnum >= 0 && G.vexnum < 100) && (G.arcnum >= 0 && G.arcnum <= 100)) {
// cout << "录入成功!\n";
// break;
// }
//else {
// cout << "你的输入有误,请从新输入。" << endl;
//}
//}
cout << G.vexnum << G.arcnum;
//2,for循环,逐个录入图的每一个结点信息(名,指针域初始化未NULL),构造表头结点表
for (int i = 0; i < G.vexnum; i++) {
cout << "请输入第 " << i + 1 << " 个顶点的名字 :";
cin >> G.vertices[i].data;
G.vertices[i].firstarc = NULL;
}
//3,for循环,输入 图的各边信息(边的依附顶点),通过依附顶点在表头结点的值获取顶点在表头结点的数组的下标值,
// 根据获取的下标,生成新的边界点,为结点的各个属性赋值,用链表前插法链入顶点的边链表中,构造邻接边表
VNode* v1 = new VNode;
VNode* v2 = new VNode;
for (int k = 0; k < G.arcnum; k++) {
cout << "请输入一条边所依附的第一个顶点 :" << endl;
cin >> v1->data;
cout << "请输入一条边所依附的第二个顶点 :" << endl;
cin >> v2->data;
int i = LocateVex(G, v1);
int j = LocateVex(G, v2);
//头插法为Vi插入新的边结点
ArcNode * p1 = new ArcNode;
cout << "请输入边的权值(整数) :";
cin >> p1->info;
p1->adjvex = j; //邻接结点在头结点表的下标
p1->nextarc = G.vertices[i].firstarc;
G.vertices[i].firstarc = p1;
//头插法为Vj插入新的边结点
ArcNode * p2 = new ArcNode;
p2->info = p1->info;
p2->adjvex = i;
p2->nextarc = G.vertices[j].firstarc;
G.vertices[j].firstarc = p2;
}
}
void Opertion_Create()
{
ALgraph G;
CreateUDG(G);
}
//定义辅助数组
bool visited[MVNum];
实现深度遍历算法
#pragma once
#include"ALG.h"
//深度遍历核心函数
void DFS(ALgraph G, int v) { //从第V个顶点开始遍历
//1,访问第V个顶点
cout << G.vertices[v].data << " ";
visited[v] = true; //置访问标志数组相应的分量值为true
ArcNode * p = G.vertices[v].firstarc; //获取被访问顶点的边链表的首元结点的指针
while (p) {
int w = p->adjvex; //获取v顶点的邻接顶点
if (visited[w]== false) //判断该顶点是否被访问过
DFS(G, w);
p = p->nextarc; //指向下一个边结点
}
}
//深度遍历测试函数
void DFS_Traverse(ALgraph G) {
//访问标志辅助数组初始化
for (int i = 0; i < MVNum; i++)
{
visited[i] = false;
}
//连通图遍历
int v;
cout << "请输入开始遍历的顶点:";
cin >> v;
DFS(G, v-1);
//非连通图遍历
/*
for (int v = 0; v < G.vexnum; v++) {
if (visited[v] == false)
DFS(G, v);
}
*/
}
void Opreation_DFS() {
//2,创建图的邻接表
ALgraph G;
CreateUDG(G);
//3,对图进行深度遍历
DFS_Traverse(G);
}
#pragma once
#include"ALG.h"
//队列结点的结构
typedef struct Qnode {
int data;
struct Qnode * next;
}Qnode, *QueuePtr;
//链表队列结构
typedef struct {
QueuePtr front; //队头指针
QueuePtr rear; //队尾指针
}LinkQueue;
//初始化队列
void InitQueue(LinkQueue &Q) {
Q.front = Q.rear = new Qnode; //生成新的结点作为头结点,初始化队头队尾指针
Q.front->next = NULL; //头结点的指针域为空
}
//链队入队
bool EnQueue(LinkQueue &Q, int e) {
Qnode * p = new Qnode; //创建一个新的结点
p->data = e;
p->next = Q.front->next;
Q.rear->next = p; //插入新节点到队尾
Q.rear = p; //修改队尾指针
return true;
}
//链队出队
bool DeQueue(LinkQueue &Q, int &e) {
if (Q.front == Q.rear)
return false;
Qnode * p; //保存头结点指针,用于释放空间
p = Q.front->next; //指向队头结点
e = p->data; //获取队头结点的元素的值
Q.front->next = p->next; //修改头指针
if (Q.rear == p) //判断删除的元素是否为最后一个元素,避免空指针异常,将队尾指针重新指向队头指针
Q.rear = Q.front;
Q.rear->next = Q.front->next; //最后一个结点指向首元结点
delete p;
return true;
}
//销毁队列
void DeleteQueue(LinkQueue &Q) {
while (Q.front)
{
Q.rear = Q.front->next;
delete Q.front;
Q.front = Q.rear;
}
}
//ALG.h头文件声明辅助数组
//广度遍历核心函数
void BFS(ALgraph G, int v) {
LinkQueue Q;
InitQueue(Q);
cout << G.vertices[v].data << " ";
visited[v] = true;
EnQueue(Q,v);
while (Q.front != Q.rear) {
int u;
DeQueue(Q, u);
ArcNode * p = G.vertices[u].firstarc; //获取被访问顶点的边链表的首元结点的指针
while (p) { // 先输入一个顶点的所有临界点
int w = p->adjvex; //获取v顶点的邻接顶点
if (visited[w] == false) {//判断该顶点是否被访问过
cout << G.vertices[w].data << " ";
visited[w] = true; //修改辅助表
EnQueue(Q, w); //已经输出的邻接点入队
}
p = p->nextarc; //指向顶点的下一个邻接点
}
}
}
//广度遍历操作函数
void BFS_Traverse(ALgraph G) {
//访问标志辅助数组初始化
for (int i = 0; i < MVNum; i++)
{
visited[i] = false;
}
//连通图遍历
int v;
cout << "请输入开始遍历的顶点:";
cin >> v;
BFS(G, v - 1);
}
void Opreation_BFS() {
//2,创建图的邻接表
ALgraph G;
CreateUDG(G);
//3,对图进行深度遍历
BFS_Traverse(G);
}
用于测试和实现头文件中的各种算法操作函数
// photos.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
#include "pch.h"
#include"ALG.h"
#include"DFS.h"
#include"BFS.h"
int main()
{
//Opertion_Create();
//Opreation_DFS();
Opreation_BFS();
}