【数据结构】第七章 图

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; 
}


  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值