1.图的定义
3.实验报告
(1) 建立图的邻接矩阵(或邻接表)存储表示,计算顶点的度(入度、出度),并实现图的深度优先或广度优先遍历。
(2) 编程实现最小生成树求解的Prim算法。
(3) 编程实现AOV网的拓扑排序。
(4) 编程求AOE网的关键路径。
(5) 编程实现单源点最短路径的Dijkstra算法。
#include <stdio.h>
#include <iostream>
using namespace std;
#include <iomanip>
#include <string.h>
#include <malloc.h>
#include <process.h>
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define OVERFLOW -1
typedef int Status;
queue_custom.h
typedef int QElemType;
typedef struct QNode{
QElemType data;
struct QNode *next;
}QNode,*QueuePtr;
typedef struct {
QueuePtr front;//队头指针
QueuePtr rear;//队尾指针
}LinkQueue;
queue_operation.h
Status InitQueue(LinkQueue &Q){
Q.front = Q.rear = (QueuePtr)malloc(sizeof(QNode));
if(!Q.front) exit(OVERFLOW) ;//存储空间分配失败
Q.front->next = NULL;
return OK;
}//建立空队列
Status QueueEmpty(LinkQueue &Q){
if(Q.front==Q.rear){
return OK;
}else{
return FALSE;
}
}
Status CreateQueue(LinkQueue &Q){
int n;
cout<<"请输入队列元素个数:"<<endl;
cin>>n;
QueuePtr p;
p = (QueuePtr)malloc(sizeof(QNode));
if(!p) exit(OVERFLOW);
for(int i=0;i<n;i++){
scanf("%d",p->data);
p=p->next;
}
p->next = NULL;
Q.rear->next = p;
Q.rear = p;
return OK;
}
Status EnQueue(LinkQueue &Q,QElemType e){
QueuePtr p;
p = (QueuePtr)malloc(sizeof(QNode));
if(!p) exit(OVERFLOW);
p->data = e;
p->next = NULL;
Q.rear->next = p;
Q.rear = p;
return OK;
}//插入队尾元素
Status DeQueue(LinkQueue &Q,QElemType &e){
QueuePtr p;
if(QueueEmpty(Q)) return ERROR;
p = Q.front->next;
e = p->data;
Q.front->next = p->next;
if(Q.rear == p)
Q.rear = Q.front;
free(p);
return OK;
}//删除队头元素
void OutputQueue(LinkQueue &Q){
QueuePtr p;
p = Q.front->next;
while(p!=NULL){
printf("%d ",p->data);
p = p->next;
}
}//输出队列
Status DestroyQueue(LinkQueue Q){
while(Q.front){
Q.rear = Q.front->next;
free(Q.front);
Q.front = Q.rear;
}
return OK;
}//销毁队列
mgraphapp.h
int LovateVex(MGraph G,VertexType v){
int i;
for (i=0;G.vexs[i]!=v;i++);
return i;
}//获取下标值
Status CreateUDN(MGraph &G){
int i,j,k;
VertexType v1,v2;
int w;
cout<<endl<<"输入图的顶点数和边数:";
cin>>G.vexnum>>G.arcnum;
cout<<endl<<"输入图的顶点信息:";
for (i=0;i<G.vexnum;i++) cin>>G.vexs[i];
for (i=0;i<G.vexnum;i++)
for (j=0;j<G.vexnum;j++) G.arcs[i][j]=INIFINITY;
cout<<endl<<"输入边的信息 v1,v2,w"<<endl;
for (k=0;k<G.arcnum;k++) {
cin>>v1;
cin>>v2;
cin>>w;
i=LovateVex(G,v1);
j=LovateVex(G,v2);
G.arcs[i][j]=w;
G.arcs[j][i]=G.arcs[i][j];
}//for k
return OK;
}//CreateUDN
Status CreateDN(MGraph &G){
int i,j,k;
VertexType v1,v2;
int w;
cout<<endl<<"输入图的顶点数和边数:";
cin>>G.vexnum>>G.arcnum;
cout<<endl<<"输入图的顶点信息:";
for (i=0;i<G.vexnum;i++) cin>>G.vexs[i];
for (i=0;i<G.vexnum;i++)
for (j=0;j<G.vexnum;j++) G.arcs[i][j]=INIFINITY;
cout<<endl<<"输入边的信息 v1,v2,w"<<endl;
for (k=0;k<G.arcnum;k++) {
cin>>v1;
cin>>v2;
cin>>w;
i=LovateVex(G,v1);
j=LovateVex(G,v2);
G.arcs[i][j]=w;
} //for k
return OK;
}//CreateDN
Status CreateUDG(MGraph &G){
int i,j,k;
VertexType v1,v2;
cout<<endl<<"输入图的顶点数和边数:";
cin>>G.vexnum>>G.arcnum;
cout<<endl<<"输入图的顶点信息:";
for (i=0;i<G.vexnum;i++) cin>>G.vexs[i];
for (i=0;i<G.vexnum;i++)
for (j=0;j<G.vexnum;j++) G.arcs[i][j]=0;
cout<<endl<<"输入边的信息 v1,v2"<<endl;
for (k=0;k<G.arcnum;k++) {
cin>>v1;
cin>>v2;
i=LovateVex(G,v1);
j=LovateVex(G,v2);
G.arcs[i][j]=1;
G.arcs[j][i]=G.arcs[i][j];
}//for k
return OK;
}//CreateUDG
Status CreateDG(MGraph &G){
int i,j,k;
VertexType v1,v2;
cout<<endl<<"输入图的顶点数和边数:";
cin>>G.vexnum>>G.arcnum;
cout<<endl<<"输入图的顶点信息:";
for (i=0;i<G.vexnum;i++) cin>>G.vexs[i];
for (i=0;i<G.vexnum;i++)
for (j=0;j<G.vexnum;j++) G.arcs[i][j]=0;
cout<<endl<<"输入边的信息 v1,v2"<<endl;
for (k=0;k<G.arcnum;k++) {
cin>>v1;
cin>>v2;
i=LovateVex(G,v1);
j=LovateVex(G,v2);
G.arcs[i][j]=1;
}//for k
return OK;
}//CreateDG
//出度
int GetOut(MGraph G,int i){
int j;
int sum=0;
for(j=0;j<G.vexnum;j++){
if(G.arcs [i][j]!=0&&G.arcs [i][j]!=INIFINITY){
sum++;
}
}
return sum;
}
//入度
int GetIn(MGraph G,int j){
int i;
int sum=0;
for(i=0;i<G.vexnum;i++){
if(G.arcs [i][j]!=0&&G.arcs [i][j]!=INIFINITY){
sum++;
}
}
return sum;
}
//度数
int GetInAndOut(MGraph G,int i){
int j;
int sum=0;
for(j=0;j<G.vexnum ;j++){
if(G.arcs [i][j]!=0&&G.arcs [i][j]!=INIFINITY){
sum++;
}
}
return sum;
}
//广度优先遍历
void BFSTraverse(MGraph G){
visited visited[MAX_VERTEX_NUM];
int v,u,w;
for(v=0;v<G.vexnum ;v++){
visited[v]=false;
}
LinkQueue (Q);
InitQueue (Q);
for(v=0;v<G.vexnum ;v++){
if(!visited[v]){
visited[v]=true;
cout<<G.vexs[v];
EnQueue(Q,v);
while(!QueueEmpty(Q)){
DeQueue(Q,u);
for(w=0;w<G.vexnum ;w++){
if((G.arcs [u][w]==1)&&(!visited[w])){
visited[w]=true;
cout<<G.vexs [w];
EnQueue(Q,w);
}
}
}
}
}
}
//深度优先遍历
void DFS(MGraph G,int v,visited *visited){
visited[v]=true;
cout<<G.vexs [v];
for(int w=0;w<G.vexnum ;w++){
if((G.arcs [v][w]==1)&&(!visited[w])){
DFS(G,w,visited);
}
}
}
void DFSTraverse(MGraph G){
visited visited[MAX_VERTEX_NUM];
int v;
for(v=0;v<G.vexnum ;v++){
visited[v]=false;
}
for(v=0;v<G.vexnum ;v++){
if(!visited[v]){
DFS(G,v,visited);
}
}
}
Status CreateGraph(MGraph &G){ //建立图G的邻接矩阵
int kind;
cout<<endl<<"输入图的类型:0-DG,1-DN,2-UDG,3-UDN:"<<endl;
cin>>kind;
G.kind=(GraphKind)kind;
switch (G.kind){
case DG :return CreateDG(G);
case DN :return CreateDN(G);
case UDG :return CreateUDG(G);
case UDN :return CreateUDN(G);
default :return ERROR;
}
}//CreateGraph
void PrintGraph(MGraph G){
int v0;
int *dist=(int *)malloc(sizeof(int)*G.vexnum );
int *path=(int *)malloc(sizeof(int)*G.vexnum );
int i,j;
cout<<endl<<"图的顶点数和边数:";
cout<<setw(3)<<G.vexnum<<setw(3)<<G.arcnum;
cout<<endl<<"图的顶点信息:"<<endl;
for (i=0;i<G.vexnum;i++) cout<<setw(3)<<G.vexs[i];
if(G.kind ==DG||G.kind ==DN){
cout<<endl<<"图的顶点出度:"<<endl;
for (i=0;i<G.vexnum;i++) cout<<setw(3)<<GetOut(G,i);
cout<<endl<<"图的顶点入度:"<<endl;
for (i=0;i<G.vexnum;i++) cout<<setw(3)<<GetIn(G,i);
}else{
cout<<endl<<"图的度数:"<<endl;
for (i=0;i<G.vexnum;i++) cout<<setw(3)<<GetInAndOut(G,i);
}
cout<<endl<<"图的邻接矩阵:"<<endl;
for (i=0;i<G.vexnum;i++){
cout<<endl;
for (j=0;j<G.vexnum;j++){
if (G.arcs[i][j]==INIFINITY)cout<<setw(5)<<"∞";
else cout<<setw(5)<<G.arcs[i][j];
}
}//for i
cout<<endl;
if(G.kind ==UDG){
cout<<endl<<"图的广度遍历:"<<endl;
BFSTraverse(G);
cout<<endl<<"图的深度遍历:"<<endl;
DFSTraverse(G);
cout<<endl;
}
}
mgraphdef.h
#define INIFINITY 1000 // 最大值
#define MAX_VERTEX_NUM 20 //最大顶点数
typedef enum{DG,DN,UDG,UDN} GraphKind; //图的四种类型
typedef char VertexType; //顶点类型
typedef bool visited;
typedef struct {
VertexType vexs[MAX_VERTEX_NUM]; //顶点向量
int arcs[MAX_VERTEX_NUM][MAX_VERTEX_NUM];//邻接矩阵
int vexnum,arcnum; //顶点数和弧的数目
GraphKind kind; //图的种类
}MGraph;
typedef struct {
VertexType adjvex;
int lowcost;
}closedge[MAX_VERTEX_NUM];
//辅助数组
main
#include "com_def.h"
#include "mgraphdef.h"
#include "queue_custom.h"
#include "queue_operation.h"
#include "mgraphapp.h"
int main(){
MGraph G;
CreateGraph(G);
PrintGraph(G);
return 0;
}