以邻接矩阵的方式确定有向网

 

/*
     题目2: 以邻接矩阵的方式确定有向网,完成:
    ⑴建立并显示出它的邻接链表;
    ⑵以非递归的方式进行深度优先遍历,显示遍历的结果,(并随时显示栈的入、出情况);
    ⑶对该图进行拓扑排序,显示拓扑排序的结果,并随时显示入度域的变化情况;
    ⑷给出某一确定顶点到所有其它顶点的最短路径
*/
#include<stdio.h>
#include<stdlib.h>
#define MAX_VERTEX_NUM 20        //最大顶点个数
#define STACK_INIT_SIZE 100      //存储空间初始分配量
#define STACKINCREMENT 10       //存储空间分配增量
#define OVERFLOW 0
#define ERROR 0
#define OK 1
#define INFINITY 100
typedef struct ArcCell     //图的邻接矩阵结构定义
{
 char adj;         //顶点
 int *info;        //弧相关信息指针
}VertexNode;
typedef struct       
{
 VertexNode vexs[MAX_VERTEX_NUM];           //顶点向量
 int arcs[MAX_VERTEX_NUM][MAX_VERTEX_NUM];    //邻接矩阵
 int vexnum,arcnum;        //定点数和弧数
}MGraph;
typedef struct      
{
 int *base;      //栈底指针
 int *top;           //栈顶指针
 int stacksize;      //存储空间
}SqStack;

int InitStack(SqStack &S)           //构造一个空栈
{
 S.base = (int *)malloc(STACK_INIT_SIZE *sizeof(int)); 
 if(!S.base)           //存储分配失败
  return OVERFLOW;
 S.top=S.base;
 S.stacksize=STACK_INIT_SIZE;
 return OK;
}

int StackEmpty(SqStack &S)      
{
 if(S.top==S.base)        //空栈
  return OK;
 else
     return ERROR;
}

int Push(SqStack &S,int e)          //插入新的栈顶元素
{
 if(S.top-S.base>=S.stacksize)      //栈满,追加存储空间
 {
  S.base=(int *)realloc(S.base,(S.stacksize+STACKINCREMENT) *sizeof(int));
     if(!S.base)          //存储分配失败
       return(OVERFLOW);
     S.top=S.base+S.stacksize;
     S.stacksize+=STACKINCREMENT;
 }
 *S.top++=e;
 return OK;
}
int GetTop(SqStack &S,int &e)
{
 if(S.top==S.base)
  return ERROR;
 e=*(S.top-1);
 return e;
}

int Pop(SqStack &S,int &e)          //删除栈顶元素
{
    if(S.top==S.base)       
  return ERROR;
 e=*--S.top;
 return e;
}

void CreatGraph(MGraph *g)//邻接矩阵创建有向网
{
 int i,j,m,r1,r2;          //m权值
 printf("请输入节点数:/n");
 scanf("%d",&g->vexnum);           //获取节点数
 printf("请输入有向网顶点信息(空格间开):/n");
 for(i=1;i<=g->vexnum;i++)           //获取顶点信息
    {
     scanf("%s",&g->vexs[i].adj);
 }
 for(i=1;i<=g->vexnum;i++)           //初始化邻接矩阵
        for(j=1;j<=g->vexnum;j++)
        {
   g->arcs[i][j]=0;
        }
 printf("请输入权值信息(以弧尾值 弧头值 权值顺序,空格间开,0 0 0结束):/n");
 scanf("%d%d%d",&r1,&r2,&m);         //权值信息
 while(r1!=0&&r2!=0&&m!=0)            //生成邻接矩阵转
    {
  g->arcs[r1][r2]=m;
  scanf("%d%d%d",&r1,&r2,&m);       
 }
}

void PrintGraph(MGraph *g)//打印有向网的邻接矩阵
{   
 int i,j;
    for(i=1;i<=g->vexnum;i++)
    {
  for(j=1;j<=g->vexnum;j++)
        {
         printf("%2d ",g->arcs[i][j]);
        }
    printf("/n");
    }
}

void PrintList(MGraph *g)//打印有向网的邻接表
{
 int i,j;
 for(i=1;i<=g->vexnum;i++)
    {
  printf("%s",&g->vexs[i].adj);  
  for(j=1;j<=g->vexnum;j++)
        {
   if(g->arcs[i][j]!=0)   //获取非零值
   {
    printf("-->%s",&g->vexs[j].adj);
   }
        }
  printf("-->NULL/n");   //一行结束,打印空
    }
}

void DFSTraverse(MGraph *g)    //非递归深度优先遍历
{
 int visited[MAX_VERTEX_NUM],i=1,j,e=1;  //visited[]标记向量,e出栈值
 SqStack s;
 InitStack(s);
 Push(s,i);            //首节点入栈
 printf("插入栈顶元素:%d/n",i);     
 printf("-->%s/n",&g->vexs[i].adj);
 visited[i]=1;       //有输出,即为1
 while(!StackEmpty(s))
 {
  
  i=e;          //从e行开始
  for(j=g->vexnum;j>=1;j--) //从右向左寻找
  {
   if(g->arcs[i][j])   //非零即入栈
   {
    Push(s,j);
    printf("插入栈顶元素:%d/n",j);
   }
  }
  Pop(s,e);       //该行最左非零值入栈
  printf("删除栈顶元素:%d/n",e); 
  if(visited[e]!=1)      //未被标记
  {
   printf("-->%s/n",&g->vexs[e].adj);
   visited[e]=1;

  }
 }
}

void FindInDegree(MGraph *g,int indegree[MAX_VERTEX_NUM]) //获取每个节点的入度,并存储在indegree数组中
{
 int i,j,n;           //n入度
 for(i=1;i<=g->vexnum;i++)
 {
  n=0;
  for(j=1;j<=g->vexnum;j++)
   if(g->arcs[j][i])      //每行非零值个数
    n++;
  indegree[i]=n;        //存储入度
 }
}

int TopologicalSort(MGraph *g)      // 拓扑排序             
{
 int indegree[MAX_VERTEX_NUM],i,j,k,count;  //count输出顶点计数
 SqStack S;
 FindInDegree(g,indegree);   //对各顶点求入度                
 InitStack(S);
 for(i=1;i<=g->vexnum;i++)    //建立零入度顶点栈                 
  if(!indegree[i])    //入度为零入栈
   Push(S,i);   
 count=0;
 while(!StackEmpty(S))
 {  
  Pop(S,i);
  printf("/n-->%s",&g->vexs[i].adj);     
  ++count;
  for(j=1;j<=g->vexnum;j++)
  {
   if(g->arcs[i][j])
   {
    k=j;
    if(!(--indegree[k]))
     Push(S,k);
    printf("/t此时%s入度:%d",&g->vexs[k].adj,indegree[k]);//若入度减为零,入栈
   }
  }

 } 
 if (count<g->vexnum)  //有回路
  return ERROR;
 else
  return OK;
}

void ShortestPath_FLOYD(MGraph *g)//任意两点最短距离
{
    int dist[MAX_VERTEX_NUM][MAX_VERTEX_NUM];//dist[]两点间路径长度
    int i,j,k;
    for(i=1;i<=g->vexnum;i++)       //初始化
        for(j=1;j<=g->vexnum;j++)
         dist[i][j]=g->arcs[i][j];
    for(i=1;i<=g->vexnum;i++)
 {
  for(j=1;j<=g->vexnum;j++)
  {
   printf("%s-->%s:/t",&g->vexs[i].adj,&g->vexs[j].adj);
   for(k=1;k<=g->vexnum;k++)
                if(i!=j&&i!=k&&j!=k)  //三点互不相同
    {
     if(dist[i][j])   //有直接路径
     {
      if(dist[i][k]&&dist[k][j])
       if(dist[i][j]>dist[i][k]+dist[k][j])  //有中间更短路径
        dist[i][j]=dist[i][k]+dist[k][j];
     }
     else
     {
      if(dist[i][k]&&dist[k][j])
       dist[i][j]=dist[i][k]+dist[k][j];//取中间路径
     }
    }
   printf("%d/n",dist[i][j]);
  }
  printf("/n");
 }
}
void main()//主函数
{
 MGraph *g=(MGraph *)malloc(sizeof(MGraph));
 CreatGraph(g);
 printf("***********************************************/n邻接矩阵输出:/n");
 PrintGraph(g);
 printf("***********************************************/n邻接链表输出:/n");
 PrintList(g);
 printf("***********************************************/n深度优先遍历:/n");
 DFSTraverse(g);
 printf("***********************************************/n拓扑排序:");
 TopologicalSort(g);
 printf("/n***********************************************/n最短路径:/n");
 ShortestPath_FLOYD(g);
}

  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值