数据结构与算法系列---图

 图的代码实现及操作:

#include  < malloc.h >
#define   MAX_VERTEX_NUM 20
#define   INF   32767   // 无穷大

#define   OK     1
#define   ERROR  0
#define   OVERFLOW -2
#define   FALSE  0
#define   TRUE   1

typedef 
enum   {DG,DN,UDG,UDN}  GraphKind;

typedef 
int  VertexType;
typedef 
struct  
{
    VertexType vexs[MAX_VERTEX_NUM
+1];               
    
int arcs[MAX_VERTEX_NUM+1][MAX_VERTEX_NUM+1];
    
int Vexnum;
    GraphKind kind;
}
MGraph;  // 邻接矩阵的存储结构

typedef 
struct  ArcNode
{
    
int adjvex;
    
struct ArcNode *nextarc;
}
ArcNode;

typedef 
struct  VNode
{
    
int data;
    ArcNode 
*firstarc;
}
VNode;

typedef 
struct
{
    VNode vertices[MAX_VERTEX_NUM
+1];
    
int vexnum,arcnum;
    GraphKind kind;
}
ALGraph; // 邻接表的存储结构


typedef 
struct  dge
{
    
int adjvex;
    
int lowcost;
}
dge,closedge[MAX_VERTEX_NUM + 1 ];

int  visited[MAX_VERTEX_NUM + 1 ];
// 创建邻接矩阵
void  Create(MGraph *  g,GraphKind kind)
{
    
int i,j;
    printf(
"input vertexs numbers:  ");
    scanf(
"%d",&g->Vexnum);
    
for(i =1;i<=g->Vexnum;i++)
    
{
        printf(
"  vertex No. %d",i);
        scanf(
"%d",&g->vexs[i]);
    }

    
for( i=1;i<=MAX_VERTEX_NUM;i++)
        
for(j=1;j<=MAX_VERTEX_NUM;j++)
            g
->arcs[i][j]=0;
    printf(
"  input edges:");
    scanf(
"%d%d",&i,&j);
    
while((i!=0)&&(j!=0))
    
{
        g
->arcs[i][j]=1;
        
if(kind==UDG)
            g
->arcs[j][i]=1;
        printf(
"  input edges:");
        scanf(
"%d%d",&i,&j);
    }

}

/*由数组生成邻接矩阵*/
void  CreateByArray(MGraph  * G,GraphKind kind, int   * array, int  dim)
{
    
int i;
    G
->kind=kind;
    G
->Vexnum=dim;
    
for(i=1;i<=dim;i++)
    
{
        G
->vexs[i]=i;
    }

    
for(i=1;i<=dim;i++)
        
for(int j=1;j<=dim;j++)
        
{
            G
->arcs[i][j]=*array++;
        }

}

/*生成图*/
void  CreateGraph(MGraph  * G)
{
    printf(
"input graph kind: 0.有向图 1,有向图 2.无向图 3.无向网  ");
    scanf(
"%d",&G->kind);
    
switch(G->kind)
    
{
        
case DG: 
            Create(G,DG);
            
break;
        
case UDG:
            Create(G,UDG);
            
break;
    }

}


/*由邻接矩阵生成邻接表*/
void  CreateALGraphByMGraph(ALGraph  * G,MGraph M)
{
    
int i,flag;
    ArcNode 
*p;
    G
->vexnum=M.Vexnum;
    G
->kind=M.kind;
    
for(i=1;i<=M.Vexnum;i++)
    
{
        G
->vertices[i].data=M.vexs[i];
        G
->vertices[i].firstarc=NULL;
    }

    
for(i=1;i<=M.Vexnum;i++)
    
{
        flag
=0;
        
for(int j=1;j<=M.Vexnum;j++)
        
{
            
if(M.arcs[i][j]!=0&&flag==0)
            
{
                p
=(ArcNode *)malloc(sizeof(ArcNode));
                p
->adjvex=j;
                p
->nextarc=NULL;
                G
->vertices[i].firstarc=p;
                flag
=1;
            }

            
else if(M.arcs[i][j]!=0&&flag==1)
            
{
                p
->nextarc=(ArcNode *)malloc(sizeof(ArcNode));
                p
=p->nextarc;
                p
->adjvex=j;
                p
->nextarc=NULL;
            }

        }
/*
        for(int j=1;j<=M.Vexnum;j++)
        {
            if(M.arcs[i][j])
            {
                p=(ArcNode *)malloc(sizeof(ArcNode));
                p->adjvex=j;
                p->nextarc=G->vertices[i].firstarc;
                G->vertices[i].firstarc=p;
            }
        }
*/

    }

}

/*遍历邻接表*/
void  TraverseALGraph(ALGraph G)
{
    
for(int i=1;i<=G.vexnum;i++)
    
{
        ArcNode 
*p=G.vertices[i].firstarc;
        printf(
"%d  ",G.vertices[i].data);
        
while(p)
        
{
            printf(
"%d  ",p->adjvex);
            p
=p->nextarc;
        }

        printf(
" ");
    }

}

/*v的第一个邻接点*/
int  FirstAdjVex(MGraph  * g, int  v)
{
    
int i;
    
for(i=1;i<g->Vexnum;i++)
        
if(g->arcs[v][i]>0&&g->arcs[v][i]<INF)
            
return i;
    
return 0;
}

/*w的邻接点*/
int  NextAdjVex(MGraph  * g, int  v, int  w)
{
    
int i=0;
    
for(i=w+1;i<g->Vexnum;i++)
        
if(g->arcs[v][i]>0&&g->arcs[v][i]<INF)
            
return i;
    
return 0;
}


void  DFS(MGraph  * g, int  v)
{
    
int w=0;
    visited[v]
=1;
    printf(
"%d  ",g->vexs[v]);
    
for(w=FirstAdjVex(g,v);w;w=NextAdjVex(g,v,w))
    
{
        
if(!visited[w])
            DFS(g,w);
    }

}

/*深度优先遍历*/
void  DFSTraverse(MGraph  * g)
{
    
int i;
    
for(i=1;i<=g->Vexnum;i++)
        visited[i]
=0;
    
for(i=1;i<=g->Vexnum;i++)
        
if(!visited[i])
            DFS(g,i);
}
 
/*邻接表的深度优先遍历*/
void  DFS2(ALGraph  * g, int  visited[], int  v)
{
    
struct ArcNode *p;
    visited[v]
=1;
    printf(
"%d, ",g->vertices[v].data);
    p
=g->vertices[v].firstarc;
    
while(p)
    
{
        
if(!visited[p->adjvex])
            DFS2(g,visited,p
->adjvex);
        p
=p->nextarc;
    }

}

/*邻接表的深度优先遍历*/
void  DFSTraverse2(ALGraph  * g, int  v)
{
    
int visited[MAX_VERTEX_NUM+1];
    
for(int i=1;i<=g->vexnum;i++)
        visited[i]
=0;
    DFS2(g,visited,v);
}


/*深度优先遍历(非递归)*/
void  Adj_NonDFS(ALGraph  * g, int  v)
{
    
int visited[MAX_VERTEX_NUM+1],i,j;
    
int stack[MAX_VERTEX_NUM+1],top=-1;
    
struct ArcNode *p;
    
for(i=1;i<=g->vexnum;i++)
        visited[i]
=FALSE;
    stack[
++top]=v;
    
while(top>-1)
    
{
        j
=stack[top--];
        printf(
"%d, ",g->vertices[j].data);
        visited[j]
=TRUE;
        p
=g->vertices[j].firstarc;
        
while(p)
        
{
            
if(!visited[p->adjvex])
                stack[
++top]=p->adjvex;
            p
=p->nextarc;
        }

    }

}


// 广度优先遍历
void  BSFTraverse(MGraph  * g)
{
    
int Q[MAX_VERTEX_NUM];
    
int front=0,rear=0;
    
int u;
    
for(int i=1;i<=g->Vexnum;i++)
    
{
        visited[i]
=FALSE;
    }

    
for(int v=1;v<=g->Vexnum;v++)
    
{
        
if(!visited[v])
        
{
            visited[v]
=TRUE;
            printf(
"%d, ",g->vexs[v]);
            Q[rear
++]=v;
            
while(rear!=front)
            
{
                u
=Q[front];
                front
=(front+1)%MAX_VERTEX_NUM;
                
for(int w=FirstAdjVex(g,u);w;w=NextAdjVex(g,u,w))
                
{
                    
if(!visited[w])
                    
{
                        visited[w]
=TRUE;
                        printf(
"%d, ",g->vexs[w]);
                        
if((rear+1)%MAX_VERTEX_NUM==front)
                        
{
                            printf(
"队列已满!");
                            
return;
                        }

                        Q[rear]
=w;
                        rear
=(rear+1)%MAX_VERTEX_NUM;
                    }

                }

            }

        }

    }

}

/*求有向图的入度*/
int  ITD(MGraph  * G, int  col)
{
    
int s=0;
    
if(G->kind!=DG)
    
{
        printf(
"Not a DG!");
        
return 0;
    }

    
for(int i=1;i<=G->Vexnum;i++)
    
{
        s
+=G->arcs[i][col];
    }

    
return s;
}

// 求有向图各顶点的度
void  FindInDegree(MGraph  * G, int   * degree)
{
    
for(int i=1;i<=G->Vexnum;i++)
        degree[i]
=ITD(G,i);
}

// 拓扑排序
int  TopologicalSort(ALGraph  * G, int   * degree)
{
    
int stack[MAX_VERTEX_NUM],top=-1,i,count=0;
    ArcNode 
*p;
    
int k;
    
for(i=1;i<=G->vexnum;i++)
        
if(!degree[i])
            stack[
++top]=i;
    
while(top>-1)
    
{
        i
=stack[top--];
        printf(
"  num %d verx %d  ",i,G->vertices[i].data);
        count
++;
        
for(p=G->vertices[i].firstarc;p;p=p->nextarc)
        
{
            k
=p->adjvex;
            
if(!(--degree[k]))
                stack[
++top]=k;
        }

    }

    
if(count<G->vexnum)
        
return ERROR;
    
else
        
return OK;
}

// 求最小的边
int  minimumver(closedge e)
{
    
int min=INF;
    
int closever;
    
for(int i=1;i<=MAX_VERTEX_NUM;i++)
    
{
        
if(e[i].lowcost>0&&e[i].lowcost<min)
        
{
            min
=e[i].lowcost;
            closever
=i;
        }

    }

    
return closever;
}

/*Prim 算法*/
void  MiniSpanTree_PRIM(MGraph  * G, int  v)
{
    closedge cdge;
    
int k;
    
for(int j=1;j<=G->Vexnum;j++)
    
{
        
if(j!=v)
        
{
            cdge[j].adjvex
=v;
            cdge[j].lowcost
=G->arcs[v][j];
        }

    }
//辅助数组初始化
    cdge[v].lowcost=0;
    
for(int i=1;i<G->Vexnum;i++)
    
{
        k
=minimumver(cdge);
        printf(
"  from %d to %d: %d  ",cdge[k].adjvex,G->vexs[k],G->arcs[cdge[k].adjvex][k]);
        cdge[k].lowcost
=0;
        
for(int j=1;j<=G->Vexnum;j++)
        
{
            
if(G->arcs[k][j]<cdge[j].lowcost)
            
{
                cdge[j].adjvex
=G->vexs[k];
                cdge[j].lowcost
=G->arcs[k][j];
            }

        }

    }

}

int  main( int  agrc, char *  argv[])
{
    MGraph G1;
    ALGraph G2;
    
int degree[9];
//    CreateGraph(&G1);
    int array[4][4]={{0,1,1,0},{0,0,0,0},{0,0,0,1},{1,0,0,0}};
//    int array[6][6]={{0,1,1,1,0,0},{0,0,0,0,0,0},{0,1,0,0,1,0},{0,0,0,0,1,0},{0,0,0,0,0,0},{0,0,0,1,1,0}};
//    int array[6][6]={{INF,6,1,5,INF,INF},{6,INF,5,INF,3,INF},{1,5,INF,5,6,4},{5,INF,5,INF,INF,2},{INF,3,6,INF,INF,6},{INF,INF,4,2,6,INF}};
//    int array[6][6]={{0,6,1,5,0,0},{6,0,5,0,3,0},{1,5,0,5,6,4},{5,0,5,0,0,2},{0,3,6,0,0,6},{0,0,4,2,6,0}};
//    int array[8][8]={{0,1,1,0,0,0,0,0},{1,0,0,1,1,0,0,0},{1,0,0,0,0,1,1,0},{0,1,0,0,0,0,0,1},{0,1,0,0,0,0,0,1},{0,0,1,0,0,0,1,0},{0,0,1,0,0,1,0,0},{0,0,0,1,1,0,0,0}};
    CreateByArray(&G1,DG,*array,4);

    printf(
"deep first traverse: ");
    DFSTraverse(
&G1);

    
    printf(
" broad traverse: ");
    BSFTraverse(
&G1);

    FindInDegree(
&G1,degree);
//    MiniSpanTree_PRIM(&G1,1);
    CreateALGraphByMGraph(&G2,G1);

    printf(
" topo sort: ");
    TopologicalSort(
&G2,degree);

//    CreateALGraphByMGraph(&G2,G1);
    printf("  traverse adj: ");
//    TraverseALGraph(G2);
    Adj_NonDFS(&G2,1);
    
    printf(
"  deep traverse adj: ");
    DFSTraverse2(
&G2,1);
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值