定义图结构体
typedef struct {
VexType vexs[MAXNUM];
ArcType arcs[MAXNUM][MAXNUM];
int vexnum, arcnum;
}AMGraph;
typedef struct ArcNode {
int adjvex;
struct ArcNode *nextarc;
/*AdjType weight;
/*InfoType *info;
}ArcNode;
typedef struct VNode {
VexType data;
ArcNode *firstarc;
}VNode, AdjList[MAXNUM];
typedef struct {
AdjList vertices;
int vexnum, arcnum;
}ALGraph;
问题:
1、编写函数,构造以邻接矩阵表示的图;
2、编写函数,构造以邻接表表示的图;
3、编写函数,实现图的深度优先遍历算法(DFS);(图用邻接表表示)
4、编写函数,实现图的广度优先遍历算法(BFS);(图用邻接表表示)(选做)
5、编写函数,实现求最小生成树的Prim算法;(图用邻接矩阵表示)
6、编写函数,实现求最短路径的Dijkstra算法。(图用邻接矩阵表示)(选做)
算法思想阐述:
邻接矩阵创建无向网:
输入总顶点数和总边数后,初始化该矩阵,使其每个权值初始化为极大值,调用LocateALGVex函数,确定两个顶点在图中的位置后,赋予相应边的权值,同时使其对称边赋予相同的权值。
邻接表创建无向图:
输入总顶点数和总边数后,使每个表头结点的指针域初始化为NULL,输入每条边依附的两个顶点后,将此边插入Vi和Vj对应的两个边链表的头部。
Prim算法:
特点:适用于稠密图,归并顶点,与边数无关
1. 从某顶点 u0 出发,选择与它关联的具有最小权值的边(u0, v),将其顶点加入到生成树的顶点集合U中
2. 每一步从一个顶点在U中,而另一个顶点不在U中的各条边中选择权值最小的边(u, v),把它的顶点加入到U中
3. 直到所有顶点都加入到生成树顶点集合U中为止
Kruskal算法:
特点:适用于稀疏图,归并边,
1.先找出从源点v0到各终点vk的直达路径(v0,vk),即通过一条弧到达的路径。
2.从这些路径中找出一条长度最短的路径(v0,u)
3.然后对其余各条路径进行适当调整:
若在图中存在弧(u,vk),且(v0,u)+(u,vk)<(v0,vk),则以路径(v0,u,vk)代替(v0,vk)
在调整后的各条路径中,再找长度最短的路径。
一、各函数代码如下
解题一
/*确定两点在邻接矩阵G中的位置,即顶点数组的下标 */
Status LocateAMGVex(AMGraph G,char x){
for(int i = 0; i < G.vexnum;i++){
if(x == G.vexs[i]){
return i;
}
}
return -1;
}
/*确定两点在邻接表G中的位置,即顶点数组的下标 */
Status LocateALGVex(ALGraph G,char x){
for(int i = 0; i < G.vexnum ;i++){
if(x == G.vertices[i].data){
return i;
}
}
return -1;
}
/*邻接矩阵创建无权无向图*/
Status CreateUDNwom(AMGraph &G){
char v1,v2;/*两顶点*/
cout<<"请输入总顶点数和总边数:"<<endl;
cin>>G.vexnum>>G.arcnum;/*输入总顶点数和总边数*/
for(int i = 0;i < G.vexnum;i++){/*将各点输入顶点表中*/
printf("请输入第%d个顶点:\n",i+1);
cin>>G.vexs[i];
}
for(int i = 0;i < G.vexnum;i++){
for(int j = 0;j < G.vexnum;j++){/*初始化邻接矩阵,使之每个权值初始化为最大值*/
G.arcs[i][j] = 0;
}
}
for(int k = 0;k < G.arcnum;k++){
printf("请输入第%d条边依附的顶点:\n",k+1);
int i,j,w = 1;
cin>>v1>>v2;/*输入一条边依附的顶点及其权值*/
i = LocateAMGVex(G,v1);
j = LocateAMGVex(G,v2);//确定两点在G中的位置,即顶点数组的下标
G.arcs[i][j] = w;/*给边赋值*/
G.arcs[j][i] = w;/*置<v1,v2>的对称边<v2,v1>权值为w*/
}
return OK;
}
/*邻接矩阵创建有权无向图*/
Status CreateUDNm(AMGraph &G){
char v1,v2;/*两顶点*/
cout<<"请输入总顶点数和总边数:"<<endl;
cin>>G.vexnum>>G.arcnum;/*输入总顶点数和总边数*/
for(int i = 0;i < G.vexnum;i++){/*将各点输入顶点表中*/
printf("请输入第%d个顶点:\n",i+1);
cin>>G.vexs[i];
}
for(int i = 0;i < G.vexnum;i++){
for(int j = 0;j < G.vexnum;j++){/*初始化邻接矩阵,使之每个权值初始化为最大值*/
G.arcs[i][j] = MAXInt;
}
}
for(int k = 0;k < G.arcnum;k++){
printf("请输入第%d条边依附的顶点及其权值:\n",k+1);
int i,j,w;/*权值*/
cin>>v1>>v2>>w;/*输入一条边依附的顶点及其权值*/
i = LocateAMGVex(G,v1);
j = LocateAMGVex(G,v2);//确定两点在G中的位置,即顶点数组的下标
G.arcs[i][j] = w;/*给边赋值*/
G.arcs[j][i] = w;/*置<v1,v2>的对称边<v2,v1>权值为w*/
}
return OK;
}
/*邻接矩阵创建无权有向图*/
Status CreateDNwom(AMGraph &G){
char v1,v2;/*两顶点*/
cout<<"请输入总顶点数和总边数:"<<endl;
cin>>G.vexnum>>G.arcnum;/*输入总顶点数和总边数*/
for(int i = 0;i < G.vexnum;i++){/*将各点输入顶点表中*/
printf("请输入第%d个顶点:\n",i+1);
cin>>G.vexs[i];
}
for(int i = 0;i < G.vexnum;i++){
for(int j = 0;j < G.vexnum;j++){/*初始化邻接矩阵,使之每个权值初始化为最大值*/
G.arcs[i][j] = 0;
}
}
for(int k = 0;k < G.arcnum;k++){
printf("请输入第%d条边依附的顶点:\n",k+1);
int i,j,w = 1;
cin>>v1>>v2;/*输入一条边依附的顶点及其权值*/
i = LocateAMGVex(G,v1);
j = LocateAMGVex(G,v2);//确定两点在G中的位置,即顶点数组的下标
G.arcs[i][j] = w;/*给边赋值*/
}
return OK;
}
/*邻接矩阵创建有权有向图*/
Status CreateDNm(AMGraph &G){
char v1,v2;/*两顶点*/
cout<<"请输入总顶点数和总边数:"<<endl;
cin>>G.vexnum>>G.arcnum;/*输入总顶点数和总边数*/
for(int i = 0;i < G.vexnum;i++){/*将各点输入顶点表中*/
printf("请输入第%d个顶点:\n",i+1);
cin>>G.vexs[i];
}
for(int i = 0;i < G.vexnum;i++){
for(int j = 0;j < G.vexnum;j++){/*初始化邻接矩阵,使之每个权值初始化为最大值*/
G.arcs[i][j] = MAXInt;
}
}
for(int k = 0;k < G.arcnum;k++){
printf("请输入第%d条边依附的顶点及其权值:\n",k+1);
int i,j,w;/*权值*/
cin>>v1>>v2>>w;/*输入一条边依附的顶点及其权值*/
i = LocateAMGVex(G,v1);
j = LocateAMGVex(G,v2);//确定两点在G中的位置,即顶点数组的下标
G.arcs[i][j] = w;/*给边赋值*/
}
return OK;
}
/*打印邻接矩阵构造的图*/
void PrintN(AMGraph G){
cout<<endl;
for(int i = 0;i < G.vexnum;i++){
for(int j = 0;j < G.vexnum;j++){
printf("%5d ",G.arcs[i][j]);
}
cout<<endl;
}
cout<<endl;
}
void InitQueue(SqQueue *Q)
{
Q->front = Q->rear = 0;
}
Status IsEmpty(SqQueue *Q)
{
if (Q->front == Q->rear)
return 1;
else
return 0;
}
void EnQueue(SqQueue *Q,int e)
{
if ((Q->rear + 1) % MAXNUM == Q->front)
return;
else
{
Q->data[Q->rear] = e;
Q->rear = (Q->rear + 1) % MAXNUM;
}
}
void DeQueue(SqQueue *Q,int *e)
{
if (Q->rear == Q->front)
return;
*e = Q->data[Q->front];
Q->front = (Q->front + 1) % MAXNUM;
}
Status FirstVertex(ALGraph graph){
if(graph.vexnum==0)
return -1;
return 0;
}
Status NextVertex(ALGraph graph,int v){
if(v==graph.vexnum-1)
return -1;
return v+1;
}
/* 边的插入*/
void insert(ALGraph* p,int a,int b){/*在图中插入边(a,b)*/
ArcNode* pp;
ArcNode* temp;
temp=new ArcNode;
temp->adjvex=b;
temp->nextarc=NULL;
pp=p->vertices[a].firstarc;
if(pp==NULL)p->vertices[a].firstarc=temp;
else{
while(pp->nextarc!=NULL)
pp=pp->nextarc;
pp->nextarc=temp;
}
}
/* 邻接表构造无向图*/
Status CreateUDG(ALGraph &G){
char v1,v2;/*两顶点*/
cout<<"请输入总顶点数(不超过100)和总边数:\n";
cin>>G.vexnum>>G.arcnum;//输入总顶点数和总边数,-> cin可连续输入
for(int i=0;i<G.vexnum;i++){
printf("请输入第%d个顶点:\n",i+1);
cin>>G.vertices[i].data; //输入顶点值
G.vertices[i].firstarc=NULL; //初始化表头结点的指针域为NULL
}
for(int k=0;k<G.arcnum;k++){
int i,j;
printf("请输入第%d条边依附的顶点:\n",k+1);
cin>>v1>>v2;
i = LocateALGVex(G,v1);
j = LocateALGVex(G,v2);
ArcNode *p1 = new ArcNode;//生成一个新的边结点*p1
p1->adjvex = j;
p1->nextarc = G.vertices[i].firstarc;
G.vertices[i].firstarc = p1; /*将新结点*p1插入至顶点vi的边表头部*/
ArcNode *p2 = new ArcNode;//生成一个新的边结点*p2
p2->adjvex = i;
p2->nextarc = G.vertices[j].firstarc;
G.vertices[j].firstarc = p2; /*将新结点*p2插入至顶点vj的边表头部*/
}
return OK;
}
/* 邻接表构造有向图*/
Status CreateDG(ALGraph &G){
char v1,v2;/*两顶点*/
cout<<"请输入总顶点数(不超过100)和总边数:\n";
cin>>G.vexnum>>G.arcnum;//输入总顶点数和总边数,-> cin可连续输入
for(int i=0;i<G.vexnum;i++){
printf("请输入第%d个顶点:\n",i+1);
cin>>G.vertices[i].data; //输入顶点值
G.vertices[i].firstarc=NULL; //初始化表头结点的指针域为NULL
}
for(int k=0;k<G.arcnum;k++){
int i,j;
printf("请输入第%d条边依附的顶点:\n",k+1);
cin>>v1>>v2;
i = LocateALGVex(G,v1);
j = LocateALGVex(G,v2);
ArcNode *p1 = new ArcNode;//生成一个新的边结点*p1
p1->adjvex = j;
p1->nextarc = G.vertices[i].firstarc;
G.vertices[i].firstarc = p1; /*将新结点*p1插入至顶点vi的边表头部*/
}
return OK;
}
/*打印邻接表构造的图*/
void PrintDN(ALGraph G){
for (int i=0;i<G.vexnum;i++) {
VNode temp = G.vertices[i]; //将G的顶点信息付给temp
ArcNode *p = temp.firstarc; //将顶点信息temp中的边信息给p
if (p == NULL){
cout<<G.vertices[i].data;
cout<<endl;
}
else {
cout<<temp.data;
while (p)
{
cout<<"->";
cout<<p->adjvex;
p = p->nextarc;
}
}
cout<<endl;
}
}
void DFS(ALGraph G, int i){
visited[i] = 1;
for(int j=0;j<G.vexnum;j++)
{
if(G.vertices[j].firstarc == NULL && !visited[j])
DFS(G,j);
}
}
void DFSTraverse(ALGraph G){ /*G可能为非连通图*/
for(int i=0;i<G.vexnum;i++)
visited[i] = 0;
for(int i=0;i<G.vexnum;i++)
{
if(!visited[i])
DFS(G, i);
}
PrintDN(G);
}
void BFS(AMGraph G)
{
int i, j;
SqQueue Q;
for (i = 0; i < G.vexnum; i++)
visited[MAXNUM] = 0;
InitQueue(&Q);
for (i = 0; i < G.vexnum; i++)
{
if (!visited[i])
{
visited[i] = 1;
printf("%d ", G.vexs[i]);
EnQueue(&Q, i);
while (!IsEmpty(&Q))
{
DeQueue(&Q, &i);
for (j = 0; j < G.vexnum; j++)
{
if (!visited[j] && G.arcs[i][j] != 32767)
{
visited[j] = 1;
printf("%d ", G.arcs[j]);
EnQueue(&Q, j);
}
}
}
}
}
}
完整代码如下
#include "iostream.h"
#include "stdio.h"
#include "stdlib.h"
#define MAXNUM 100
#define MAXInt 32767
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define MAXQSIZE 100 /*最大队列长度*/
typedef int Status;/*返回类型*/
typedef char VexType;/*顶点的数据类型*/
typedef int ArcType;/*边的权值类型*/
typedef int QElemType;/*队列基地址类型*/
/*typedef float AdjType; */
/*typedef char InfoType; */
/*图的邻接矩阵*/
typedef struct {
VexType vexs[MAXNUM];/*顶点表*/
ArcType arcs[MAXNUM][MAXNUM];/*邻接矩阵*/
int vexnum, arcnum; /*图的当前顶点数和边数*/
}AMGraph;
typedef struct ArcNode {
int adjvex; /* 该弧所指向的顶点的位置*/
struct ArcNode *nextarc; /* 指向下一条弧的指针*/
/*AdjType weight;*/ /* 边的权,非带权图可以省略 */
/*InfoType *info;*/ /* 该弧相关信息的指针 可以省略*/
}ArcNode;
typedef struct VNode {
VexType data; /* 顶点信息*/
ArcNode *firstarc; /*指向第一条依附该顶点的指针*/
}VNode, AdjList[MAXNUM];
typedef struct {
AdjList vertices;
int vexnum, arcnum; /*图的当前顶点数和边数*/
}ALGraph;
int visited[MAXNUM];
typedef struct {
QElemType *data; /* 存储空间基地址*/
int front; /* 头指针,若队列不空,指向队列头元素*/
int rear; /* 尾指针,若队列不空,指向队列尾元素 的下一个位置*/
}SqQueue;
/*确定两点在邻接矩阵G中的位置,即顶点数组的下标 */
Status LocateAMGVex(AMGraph G,char x){
for(int i = 0; i < G.vexnum;i++){
if(x == G.vexs[i]){
return i;
}
}
return -1;
}
/*确定两点在邻接表G中的位置,即顶点数组的下标 */
Status LocateALGVex(ALGraph G,char x){
for(int i = 0; i < G.vexnum ;i++){
if(x == G.vertices[i].data){
return i;
}
}
return -1;
}
/*邻接矩阵创建无权无向图*/
Status CreateUDNwom(AMGraph &G){
char v1,v2;/*两顶点*/
cout<<"请输入总顶点数和总边数:"<<endl;
cin>>G.vexnum>>G.arcnum;/*输入总顶点数和总边数*/
for(int i = 0;i < G.vexnum;i++){/*将各点输入顶点表中*/
printf("请输入第%d个顶点:\n",i+1);
cin>>G.vexs[i];
}
for(int i = 0;i < G.vexnum;i++){
for(int j = 0;j < G.vexnum;j++){/*初始化邻接矩阵,使之每个权值初始化为最大值*/
G.arcs[i][j] = 0;
}
}
for(int k = 0;k < G.arcnum;k++){
printf("请输入第%d条边依附的顶点:\n",k+1);
int i,j,w = 1;
cin>>v1>>v2;/*输入一条边依附的顶点及其权值*/
i = LocateAMGVex(G,v1);
j = LocateAMGVex(G,v2);//确定两点在G中的位置,即顶点数组的下标
G.arcs[i][j] = w;/*给边赋值*/
G.arcs[j][i] = w;/*置<v1,v2>的对称边<v2,v1>权值为w*/
}
return OK;
}
/*邻接矩阵创建有权无向图*/
Status CreateUDNm(AMGraph &G){
char v1,v2;/*两顶点*/
cout<<"请输入总顶点数和总边数:"<<endl;
cin>>G.vexnum>>G.arcnum;/*输入总顶点数和总边数*/
for(int i = 0;i < G.vexnum;i++){/*将各点输入顶点表中*/
printf("请输入第%d个顶点:\n",i+1);
cin>>G.vexs[i];
}
for(int i = 0;i < G.vexnum;i++){
for(int j = 0;j < G.vexnum;j++){/*初始化邻接矩阵,使之每个权值初始化为最大值*/
G.arcs[i][j] = MAXInt;
}
}
for(int k = 0;k < G.arcnum;k++){
printf("请输入第%d条边依附的顶点及其权值:\n",k+1);
int i,j,w;/*权值*/
cin>>v1>>v2>>w;/*输入一条边依附的顶点及其权值*/
i = LocateAMGVex(G,v1);
j = LocateAMGVex(G,v2);//确定两点在G中的位置,即顶点数组的下标
G.arcs[i][j] = w;/*给边赋值*/
G.arcs[j][i] = w;/*置<v1,v2>的对称边<v2,v1>权值为w*/
}
return OK;
}
/*邻接矩阵创建无权有向图*/
Status CreateDNwom(AMGraph &G){
char v1,v2;/*两顶点*/
cout<<"请输入总顶点数和总边数:"<<endl;
cin>>G.vexnum>>G.arcnum;/*输入总顶点数和总边数*/
for(int i = 0;i < G.vexnum;i++){/*将各点输入顶点表中*/
printf("请输入第%d个顶点:\n",i+1);
cin>>G.vexs[i];
}
for(int i = 0;i < G.vexnum;i++){
for(int j = 0;j < G.vexnum;j++){/*初始化邻接矩阵,使之每个权值初始化为最大值*/
G.arcs[i][j] = 0;
}
}
for(int k = 0;k < G.arcnum;k++){
printf("请输入第%d条边依附的顶点:\n",k+1);
int i,j,w = 1;
cin>>v1>>v2;/*输入一条边依附的顶点及其权值*/
i = LocateAMGVex(G,v1);
j = LocateAMGVex(G,v2);//确定两点在G中的位置,即顶点数组的下标
G.arcs[i][j] = w;/*给边赋值*/
}
return OK;
}
/*邻接矩阵创建有权有向图*/
Status CreateDNm(AMGraph &G){
char v1,v2;/*两顶点*/
cout<<"请输入总顶点数和总边数:"<<endl;
cin>>G.vexnum>>G.arcnum;/*输入总顶点数和总边数*/
for(int i = 0;i < G.vexnum;i++){/*将各点输入顶点表中*/
printf("请输入第%d个顶点:\n",i+1);
cin>>G.vexs[i];
}
for(int i = 0;i < G.vexnum;i++){
for(int j = 0;j < G.vexnum;j++){/*初始化邻接矩阵,使之每个权值初始化为最大值*/
G.arcs[i][j] = MAXInt;
}
}
for(int k = 0;k < G.arcnum;k++){
printf("请输入第%d条边依附的顶点及其权值:\n",k+1);
int i,j,w;/*权值*/
cin>>v1>>v2>>w;/*输入一条边依附的顶点及其权值*/
i = LocateAMGVex(G,v1);
j = LocateAMGVex(G,v2);//确定两点在G中的位置,即顶点数组的下标
G.arcs[i][j] = w;/*给边赋值*/
}
return OK;
}
/*打印邻接矩阵构造的图*/
void PrintN(AMGraph G){
cout<<endl;
for(int i = 0;i < G.vexnum;i++){
for(int j = 0;j < G.vexnum;j++){
printf("%5d ",G.arcs[i][j]);
}
cout<<endl;
}
cout<<endl;
}
void InitQueue(SqQueue *Q)
{
Q->front = Q->rear = 0;
}
Status IsEmpty(SqQueue *Q)
{
if (Q->front == Q->rear)
return 1;
else
return 0;
}
void EnQueue(SqQueue *Q,int e)
{
if ((Q->rear + 1) % MAXNUM == Q->front)
return;
else
{
Q->data[Q->rear] = e;
Q->rear = (Q->rear + 1) % MAXNUM;
}
}
void DeQueue(SqQueue *Q,int *e)
{
if (Q->rear == Q->front)
return;
*e = Q->data[Q->front];
Q->front = (Q->front + 1) % MAXNUM;
}
Status FirstVertex(ALGraph graph){
if(graph.vexnum==0)
return -1;
return 0;
}
Status NextVertex(ALGraph graph,int v){
if(v==graph.vexnum-1)
return -1;
return v+1;
}
/* 边的插入*/
void insert(ALGraph* p,int a,int b){/*在图中插入边(a,b)*/
ArcNode* pp;
ArcNode* temp;
temp=new ArcNode;
temp->adjvex=b;
temp->nextarc=NULL;
pp=p->vertices[a].firstarc;
if(pp==NULL)p->vertices[a].firstarc=temp;
else{
while(pp->nextarc!=NULL)
pp=pp->nextarc;
pp->nextarc=temp;
}
}
/* 邻接表构造无向图*/
Status CreateUDG(ALGraph &G){
char v1,v2;/*两顶点*/
cout<<"请输入总顶点数(不超过100)和总边数:\n";
cin>>G.vexnum>>G.arcnum;//输入总顶点数和总边数,-> cin可连续输入
for(int i=0;i<G.vexnum;i++){
printf("请输入第%d个顶点:\n",i+1);
cin>>G.vertices[i].data; //输入顶点值
G.vertices[i].firstarc=NULL; //初始化表头结点的指针域为NULL
}
for(int k=0;k<G.arcnum;k++){
int i,j;
printf("请输入第%d条边依附的顶点:\n",k+1);
cin>>v1>>v2;
i = LocateALGVex(G,v1);
j = LocateALGVex(G,v2);
ArcNode *p1 = new ArcNode;//生成一个新的边结点*p1
p1->adjvex = j;
p1->nextarc = G.vertices[i].firstarc;
G.vertices[i].firstarc = p1; /*将新结点*p1插入至顶点vi的边表头部*/
ArcNode *p2 = new ArcNode;//生成一个新的边结点*p2
p2->adjvex = i;
p2->nextarc = G.vertices[j].firstarc;
G.vertices[j].firstarc = p2; /*将新结点*p2插入至顶点vj的边表头部*/
}
return OK;
}
/* 邻接表构造有向图*/
Status CreateDG(ALGraph &G){
char v1,v2;/*两顶点*/
cout<<"请输入总顶点数(不超过100)和总边数:\n";
cin>>G.vexnum>>G.arcnum;//输入总顶点数和总边数,-> cin可连续输入
for(int i=0;i<G.vexnum;i++){
printf("请输入第%d个顶点:\n",i+1);
cin>>G.vertices[i].data; //输入顶点值
G.vertices[i].firstarc=NULL; //初始化表头结点的指针域为NULL
}
for(int k=0;k<G.arcnum;k++){
int i,j;
printf("请输入第%d条边依附的顶点:\n",k+1);
cin>>v1>>v2;
i = LocateALGVex(G,v1);
j = LocateALGVex(G,v2);
ArcNode *p1 = new ArcNode;//生成一个新的边结点*p1
p1->adjvex = j;
p1->nextarc = G.vertices[i].firstarc;
G.vertices[i].firstarc = p1; /*将新结点*p1插入至顶点vi的边表头部*/
}
return OK;
}
/*打印邻接表构造的图*/
void PrintDN(ALGraph G){
for (int i=0;i<G.vexnum;i++) {
VNode temp = G.vertices[i]; //将G的顶点信息付给temp
ArcNode *p = temp.firstarc; //将顶点信息temp中的边信息给p
if (p == NULL){
cout<<G.vertices[i].data;
cout<<endl;
}
else {
cout<<temp.data;
while (p)
{
cout<<"->";
cout<<p->adjvex;
p = p->nextarc;
}
}
cout<<endl;
}
}
void DFS(ALGraph G, int i){
visited[i] = 1;
for(int j=0;j<G.vexnum;j++)
{
if(G.vertices[j].firstarc == NULL && !visited[j])
DFS(G,j);
}
}
void DFSTraverse(ALGraph G){ /*G可能为非连通图*/
for(int i=0;i<G.vexnum;i++)
visited[i] = 0;
for(int i=0;i<G.vexnum;i++)
{
if(!visited[i])
DFS(G, i);
}
PrintDN(G);
}
void BFS(AMGraph G)
{
int i, j;
SqQueue Q;
for (i = 0; i < G.vexnum; i++)
visited[MAXNUM] = 0;
InitQueue(&Q);
for (i = 0; i < G.vexnum; i++)
{
if (!visited[i])
{
visited[i] = 1;
printf("%d ", G.vexs[i]);
EnQueue(&Q, i);
while (!IsEmpty(&Q))
{
DeQueue(&Q, &i);
for (j = 0; j < G.vexnum; j++)
{
if (!visited[j] && G.arcs[i][j] != 32767)
{
visited[j] = 1;
printf("%d ", G.arcs[j]);
EnQueue(&Q, j);
}
}
}
}
}
}
void Switcie(){
AMGraph G1;
AMGraph G2;
AMGraph G3;
AMGraph G4;
ALGraph G5;
ALGraph G6;
int choice;
while(1){
cout<<"\n******************************选择******************************\n";
cout<<"|1.邻接矩阵构造无权无向图 2.邻接矩阵构造有权无向图 |\n";
cout<<"|3.邻接矩阵构造无权有向图 4.邻接矩阵构造有权有向图 |\n";
cout<<"|5.邻接表构造无向图 6.邻接表构造有向图 |\n";
cout<<"|7.深度优先遍历邻接表构造的图 8.广度优先遍历邻接表构造的图| \n";
cout<<"请输入选项:";
cin>>choice;
switch(choice)
{
case 1:
if(CreateUDNwom(G1) == 1){
cout<<endl<<"邻接矩阵构造无权无向图完成!!!"<<endl;
PrintN(G1);
}
system("pause");
system("cls");
Switcie();
case 2:
if(CreateUDNm(G2) == 1){
cout<<endl<<"邻接矩阵构造有权无向图完成!!!"<<endl;
PrintN(G2);
}
system("pause");
system("cls");
Switcie();
case 3:
if(CreateDNwom(G3) == 1){
cout<<endl<<"邻接矩阵构造无权有向图完成!!!"<<endl;
PrintN(G3);
}
system("pause");
system("cls");
Switcie();
case 4:
if(CreateDNm(G4) == 1){
cout<<endl<<"邻接矩阵构造有权有向图完成!!!"<<endl;
PrintN(G4);
}
system("pause");
system("cls");
Switcie();
case 5:
if(CreateUDG(G5) == 1){
cout<<endl<<"邻接表构造无向图完成!!!"<<endl<<"以0作为头结点依次向下命名!!!"<<endl<<endl;
PrintDN(G5);
}
system("pause");
system("cls");
Switcie();
case 6:
if(CreateDG(G6) == 1){
cout<<endl<<"邻接表构造有向图完成!!!"<<endl<<"以0作为头结点依次向下命名!!!"<<endl<<endl;
PrintDN(G6);
}
system("pause");
system("cls");
Switcie();
case 7:
if(CreateUDG(G5) == 1){
cout<<endl<<"邻接表构造无向图完成!!!"<<endl<<"以0作为头结点依次向下命名!!!"<<endl<<"深度优先遍历如下:"<<endl;
DFSTraverse(G5);
}
system("pause");
system("cls");
Switcie();
case 8:
if(CreateUDNm(G2) == 1){
cout<<endl<<"广度优先遍历如下:"<<endl;
BFS(G2);
}
system("pause");
system("cls");
Switcie();
default:
cout<<"您所输入的选项有误!!!"<<endl;
system("pause");
system("cls");
Switcie();
}
}
}
int main()
{
Switcie();
return 0;
}
以上解决1~4题
第5题
#include <stdio.h>
#include <stdlib.h>
#define VertexMax 20
#define MaxInt 32767
typedef char VertexType;
typedef struct
{
VertexType Vertex[VertexMax];
int AdjMatrix[VertexMax][VertexMax];
int vexnum,arcnum;
}AMGraph;
typedef struct
{
VertexType adjvex;
int lowcost;
}ShortEdge;
int LocateVex(AMGraph *G,VertexType v)
{
int i;
for(i=0;i<G->vexnum;i++)
{
if(v==G->Vertex[i])
{
return i;
}
}
printf("No Such Vertex!\n");
return -1;
}
void CreateUDN(AMGraph *G)
{
int i,j;
printf("输入顶点个数和边数:\n");
printf("顶点数 n=");
scanf("%d",&G->vexnum);
printf("边 数 e=");
scanf("%d",&G->arcnum);
printf("\n");
printf("\n");
printf("输入顶点元素(无需空格隔开):");
scanf("%s",G->Vertex);
printf("\n");
for(i=0;i<G->vexnum;i++)
for(j=0;j<G->vexnum;j++)
{
G->AdjMatrix[i][j]=MaxInt;
}
int n,m;
VertexType v1,v2;
int w;
printf("请输入边的信息和权值(例:AB,15):\n");
for(i=0;i<G->arcnum;i++)
{
printf("输入第%d条边信息及权值:",i+1);
scanf(" %c%c,%d",&v1,&v2,&w);
n=LocateVex(G,v1);
m=LocateVex(G,v2);
if(n==-1||m==-1)
{
printf("NO This Vertex!\n");
return;
}
G->AdjMatrix[n][m]=w;
G->AdjMatrix[m][n]=w;
}
}
void print(AMGraph G)
{
int i,j;
printf("\n-------------------------------");
printf("\n 邻接矩阵:\n\n");
printf("\t ");
for(i=0;i<G.vexnum;i++)
printf("\t%c",G.Vertex[i]);
printf("\n");
for(i=0;i<G.vexnum;i++)
{
printf("\t%c",G.Vertex[i]);
for(j=0;j<G.vexnum;j++)
{
if(G.AdjMatrix[i][j]==MaxInt)
printf("\t∞");
else printf("\t%d",G.AdjMatrix[i][j]);
}
printf("\n");
}
}
int minimal(AMGraph *G,ShortEdge *shortedge)
{
int i,j;
int min,loc;
min=MaxInt;
for(i=1;i<G->vexnum;i++)
{
if(min>shortedge[i].lowcost&&shortedge[i].lowcost!=0)
{
min=shortedge[i].lowcost;
loc=i;
}
}
return loc;
}
void MiniSpanTree_Prim(AMGraph *G,VertexType start)
{
int i,j,k;
ShortEdge shortedge[VertexMax];
k=LocateVex(G,start);
for(i=0;i<G->vexnum;i++)
{
shortedge[i].adjvex=start;
shortedge[i].lowcost=G->AdjMatrix[k][i];
}
shortedge[k].lowcost=0;
for(i=0;i<G->vexnum-1;i++)
{
k=minimal(G,shortedge);
printf("%c->%c,%d\n",shortedge[k].adjvex,G->Vertex[k],shortedge[k].lowcost);
shortedge[k].lowcost=0;
for(j=0;j<G->vexnum;j++)
{
if(G->AdjMatrix[k][j]<shortedge[j].lowcost)
{
shortedge[j].lowcost=G->AdjMatrix[k][j];
shortedge[j].adjvex=G->Vertex[k];
}
}
}
}
int main()
{
VertexType start;
AMGraph G;
CreateUDN(&G);
print(G);
printf("请输入起始点:");
scanf(" %c",&start);
MiniSpanTree_Prim(&G,start);
return 0;
}
第6题
#include<cstdio>
using namespace std;
#define max 10000
#define inf 20000
int n,e;
int cost[20][20];
int dist[20];
int pre[20];
int S[20];
void Dijkstra(int v){
for(int i=0;i<n;i++){
dist[i]=cost[v][i];
S[i]=0;
if(dist[i]<max)
pre[i]=v;
else
pre[i]=-1;
}
S[0]=1;
for(int i=0;i<n-1;i++){
int u;
int min=inf;
for(int j=0;j<n;j++){
if((!S[j])&&dist[j]<min){
min=dist[j];
u=j;
}
}
S[u]=1;
for(int k=0;k<n;k++){
if((!S[k])&&dist[k]>dist[u]+cost[u][k]){
dist[k]=dist[u]+cost[u][k];
pre[k]=u;
}
}
}
printf("\nThe result:\n");
for(int i=0;i<n;i++){
printf("<%d,%d>: ",v+1,i+1);
int p=pre[i];
if(p!=-1){
printf("%d ",dist[i]);
printf("%d",i+1);
while(p!=v){
printf("<--%d",p+1);
p=pre[p];
}
printf("<--%d",v+1);
}
else{
printf("inf");
}
printf("\n");
}
}
int main(){
printf("请输入顶点数和边数:");
scanf("%d%d",&n,&e);
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
cost[i][j]=max;
int start,end,dut;
for(int i=0;i<e;i++){
scanf("%d%d%d",&start,&end,&dut);
start--;
end--;
cost[start][end]=dut;
}
int v=0;
Dijkstra(v);
return 0;
}
分享完毕~
欢迎小伙伴们在文下评论和私信喔~