// GG.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <stdlib.h>
/************************************************************************/
/* 图的种类 */
/************************************************************************/
typedef enum {
DG,DN,UDG,UDN //{有向图,有向网,无向图,无向网}
}GraphKind;
/************************************************************************/
/* 全局变量 */
/************************************************************************/
//最多顶点数
#define INFINITY INT_MAX //最大值(无穷大)
#define MAX_VERTEX_NUM 30
typedef char VertexType;
typedef char InfoType;
/************************************************************************/
/* 邻接矩阵 */
/************************************************************************/
typedef struct ArcCell { // 弧的定义
int adj; // VRType是顶点关系类型。
// 对无权图,用1或0表示相邻否;
// 对带权图,则为权值类型。
InfoType *info; // 该弧相关信息的指针
} ArcCell;
typedef struct { // 图的定义
VertexType vexs[MAX_VERTEX_NUM]; // 顶点信息
ArcCell arcs[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
// 弧的信息
int vexnum, arcnum; // 顶点数,弧数
GraphKind kind; // 图的种类标志
} MGraph;
/************************************************************************/
/* 邻接表 */
/************************************************************************/
typedef struct ArcNode {
int adjvex;//该弧所指向的顶点的位置
struct ArcNode *nextarc;//指向下一条弧的指针
int weight;
InfoType *info;// 该弧相关信息指针
}ArcNode;
typedef struct VNode {
VertexType data;//该顶点的信息
ArcNode *firstarc;//指向第一条依附该顶点的弧的指针
}VNode,AdjList[MAX_VERTEX_NUM];
typedef struct {
AdjList vertices;
int vexnum,arcnum;//图当前定点数和弧数
int kind; //图的种类标志
}ALGraph;
/************************************************************************/
/* 十字链表 */
/************************************************************************/
typedef struct ArcBox { // 弧的结构表示
int tailvex, headvex; // 该弧的尾和头顶点的位置
InfoType *info; // 该弧的相关信息
struct ArcBox *hlink, *tlink; // 弧头相同和弧尾相同的弧的链域
int weight;
}ArcBox;
typedef struct VexNode { // 顶点的结构表示
VertexType data;
ArcBox *firstin,*firstout; //分别指向该顶点第一条入弧和出弧 ;
int use;
}VexNode;
typedef struct{
VexNode xlist[MAX_VERTEX_NUM];
int vexnum,arcnum;
int length;
}OLGraph;
/************************************************************************/
/* 邻接多重表 */
/************************************************************************/
typedef enum { unvisted,visted } VisitIf;
typedef struct EBox {
VisitIf mark; // 访问标记
int ivex, jvex;
//该边依附的两个顶点的位置
struct EBox *ilink, *jlink;
InfoType *info; // 该边信息指针
} EBox;
typedef struct VexBox {
VertexType data;
EBox *firstedge; // 指向第一条依附该顶点的边
} VexBox;
typedef struct { // 邻接多重表
VexBox adjmulist[MAX_VERTEX_NUM];
int vexnum, edgenum;
}AMLGraph;
//---------------------------------------------------------------------
typedef char ElemType;
typedef struct CSNode {
ElemType data;
struct CSNode *firstchild,*nextsibling;
}CSNode,*CSTree;
//-----------------------------------------------------------
#define STACK_INIT_SIZE 100
#define STACKINCREMENT 10
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(0);
S.stacksize = STACK_INIT_SIZE ;
S.top = S.base;
return(1);
}
bool StackEmpty (SqStack S){
if(S.base==S.top)
return(true);//栈空的条件
return(false);
}
int Pop(SqStack &S, int &e){
if(S.base==S.top)
return(0);//栈空
//e=*--S.top;
S.top--;
e=*S.top;
return(1);
}
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 (0);
S.stacksize += STACKINCREMENT ;
}
*S.top=e ;
S.top++;
return(1);
}
//-----------------------------------------------------------
//---------------------------------------------------------
typedef struct QNode {
int data;
struct QNode *next;
}QNode, *QueuePtr;
typedef struct {
QueuePtr front;
QueuePtr rear;
}LinkQueue;
void InitQueue(LinkQueue &Q){
Q.front=Q.rear=NULL;
}
bool QueueEmpty(LinkQueue Q){
if(!Q.front)
return(true);
return false;
}
void EnQueue(LinkQueue &Q, int e){
QNode *p=(QNode *)malloc(sizeof(QNode));
if (!p)
return;
p->data= e, p->next=NULL;
if(Q.front )
{
Q.rear->next=p;Q.rear=p;
}else
Q.front = Q.rear=p;
}
void DeQueue(LinkQueue &Q,int &e){
QNode *p;
if( !Q.front) return;
p=Q.front;
e=p->data;
Q.front=p->next;
free(p);
if(!Q.front) Q.rear=NULL;
}
//----------------------------------------------------------------------
//---------------------------------------------------------------------------------
#define INT_MAX 100
/************************************************************************/
/* 查看一个节点在邻接表中的位置 */
/************************************************************************/
int LocateVex(ALGraph G,char v){
for(int i = 0; i < G.vexnum; i++){
if(G.vertices[i].data == v) return(i);
}
return(-1);
}
/************************************************************************/
/* 创建表 */
/************************************************************************/
void CreateALGraph(ALGraph &G){
printf("请输入节点数和边数: /n");
fflush(stdin);
scanf("%d%d",&G.vexnum,&G.arcnum);
for(int i=0;i<G.vexnum;i++){
printf("请输入第%d个顶点的信息:/n",(i+1));
fflush(stdin);
scanf("%c",&G.vertices[i].data);
G.vertices[i].firstarc=NULL;
}//输入顶点信息
for(int j=0;j<G.arcnum;j++){ //输入边的信息
char v,w;
printf("请输入第%d条弧先关联的两个顶点:/n",j+1);
fflush(stdin);
scanf("%c%c",&v, &w);//形式2
ArcNode *p;
p=new ArcNode;//建立结点
if(!p) {
printf("建立节点失败!!!");
return ;
}
printf("请输入该弧的权值:/n");
fflush(stdin);
scanf("%d",&p->weight);//形式2
p->adjvex=LocateVex(G,w);
p->nextarc=G.vertices[LocateVex(G,v)].firstarc;
G.vertices[LocateVex(G,v)].firstarc=p;
}
}
/************************************************************************/
/* 打印邻接表 */
/************************************************************************/
void printALGraph(ALGraph G){
for(int i=0;i<G.vexnum;i++){
printf("%c",G.vertices[i].data);
printf(" ");
while(G.vertices[i].firstarc!=NULL){
//cout<<G.vertices[i].firstarc->adjvex<<" ";
printf("%c",G.vertices[G.vertices[i].firstarc->adjvex]);
printf(" ");
G.vertices[i].firstarc=G.vertices[i].firstarc->nextarc;
}
printf("/n");
}
}
void Convert(ALGraph A,OLGraph &G){
G.length=G.vexnum=A.vexnum;
G.arcnum=A.arcnum;
for(int i=0;i<G.length;i++){
G.xlist[i].data=A.vertices[i].data;
G.xlist[i].use=1;
G.xlist[i].firstin=G.xlist[i].firstout=NULL;
}
ArcNode *arcNode;
ArcBox *arcBox;
for(i = 0; i < G.length; i++){
arcNode = A.vertices[i].firstarc;
while(arcNode){
arcBox = (ArcBox *)malloc(sizeof(ArcBox));
if(!arcBox) exit(1);
arcBox->tailvex = i;
arcBox->headvex = arcNode->adjvex;
arcBox->tlink = G.xlist[arcBox->tailvex].firstout;
arcBox->hlink = G.xlist[arcBox->headvex].firstin;
G.xlist[arcBox->tailvex].firstout = G.xlist[arcBox->headvex].firstin = arcBox;
arcNode = arcNode->nextarc;
}
}
}
/************************************************************************/
/* 点u到其余各顶点的最短路径 */
/************************************************************************/
int prev[INT_MAX];//prev[v]表示从源s到顶点v的最短路径上顶点的前驱顶点。
bool P[INT_MAX][INT_MAX]; //p[i][w]为true时w为v到i当前求的最短路径上的顶点
int D[INT_MAX]; //D[w]存放顶点w的权值
//得到边<i,j>的权值
int getWei(ALGraph G,int i,int j){
ArcNode *s;
s=G.vertices[i].firstarc;
// printf("边的起点%d/n",i);
while(s&&s->adjvex!=j){
// printf("找边%d/n",s->adjvex);
s=s->nextarc;
}
if(s)
return s->weight;
else
return INT_MAX;
}
void ShortestPath_DIJ(ALGraph G,int v){
int i=0,j,v0,w,min;
bool final[INT_MAX]; //当final[w]为true,已经求的从v到w得最短路径
for(v0=0;v0<G.vexnum;v0++){
prev[v0]=-1;
final[v0]=false;
// printf("初始化/n");
D[v0]=getWei(G,v,v0);
for(w=0;w<G.vexnum;++w) P[v0][w]=false; // 设空路径
if(D[v0]<INT_MAX){ //顶点i与源点v邻接
prev[v0]=v;
P[v0][v]=true;
P[v0][v0] =true;
}
}
D[v]=0; final[v]=true;
//主循环,每次求得v0到某个顶点v的最短路径,并将v加到S集中
for(i=1;i<G.vexnum;++i){
//当前所知离v顶点的最近距离
min=INT_MAX;
for(w=0;w<G.vexnum;++w){
if(!final[w])
if(D[w]<min){
v0=w; min=D[w];
}
}
if(v0==G.vexnum){
break;
}
final[v0]=true; //更新当前最短路径及距离
for(w=0;w<G.vexnum;++w)
if(!final[w]&&(min+getWei(G,v0,w)<D[w])){
prev[w]=v0;
D[w]=min+getWei(G,v0,w);
for(j=0;j<G.vexnum;j++) P[w][j]=P[v0][j];
P[w][w]=true;
}
}
}
//-----------输出最短路径
void printPath(ALGraph G,int v){
int i,k;
SqStack s;
InitStack(s);
int a;
for(i=0;i<G.vexnum;i++){
if(i!=v){
if(D[i]!=INT_MAX){
printf("%c到%c的最短路径长度为:%d/n",G.vertices[v].data,G.vertices[i].data,D[i]);
printf("%c到%c的最短路径为:",G.vertices[v].data,G.vertices[i].data);
Push(s,i);
for(k=prev[i];k>-1;k=prev[k]){
a=G.vertices[k].data;
Push(s,k);
}
while(!StackEmpty(s)){
Pop(s,a);
printf("%c/t",G.vertices[a].data);
}
printf("/n");
}
else
printf("%c到%c不存在最短路径/n",G.vertices[v].data,G.vertices[i].data);
}
}
}
//--------------------任两点间的最短路径----------------------
void AllShortestPath(ALGraph G){
int i;
for(i=0;i<G.vexnum;i++){
ShortestPath_DIJ(G,i);
printPath(G,i);
}
}
//---------------------------------------------------------------------------------
/************************************************************************/
/* 查看一个节点在十字链表中的位置 */
/************************************************************************/
int LocateVex(OLGraph G,VertexType v){
for(int i = 0; i < MAX_VERTEX_NUM; i++){
if(G.xlist[i].data == v) {
if(G.xlist[i].use==0){
printf("该节点已被删除!!!");
return(-1);
}else
return(i);
}
}
return(-1);
}
/************************************************************************/
/* 采用十字链表存储表示,构造有向图 */
/************************************************************************/
void CreateOLGraph(OLGraph &G){
printf("请输入节点数和边数: /n");
fflush(stdin); //清空缓冲
scanf("%d%d",&G.vexnum, &G.arcnum);
printf("/n");
int i;
for(i = 0; i < G.vexnum; i++){ //输入顶点,按照输入的先后次序存放到数组中
printf("请输入第%d节点值: /n",i);
fflush(stdin);
scanf("%c", &G.xlist[i].data);
printf("/n");
G.xlist[i].firstin = G.xlist[i].firstout = NULL;
G.xlist[i].use=1;
}
printf("/n");
VertexType tail, head;
ArcBox *arcNode;
for(i = 0; i < G.arcnum; i++){
printf("请输边的起始点: /n");
fflush(stdin); //清空缓冲
scanf("%c%c", &tail, &head);
printf("请输入改变的权值: /n");
fflush(stdin);
arcNode = (ArcBox *)malloc(sizeof(ArcBox));
if(!arcNode) exit(1);
arcNode->tailvex = LocateVex(G, tail);
arcNode->headvex = LocateVex(G, head);
scanf("%d",&arcNode->weight);
arcNode->tlink = G.xlist[arcNode->tailvex].firstout;
arcNode->hlink = G.xlist[arcNode->headvex].firstin;
G.xlist[arcNode->tailvex].firstout = G.xlist[arcNode->headvex].firstin = arcNode;
}
G.length=G.vexnum;
}
/************************************************************************/
/* 计算节点的出度 */
/************************************************************************/
int outDegree(OLGraph G, VertexType vex)
{
int count=0;
int vertex = LocateVex(G, vex);
if(G.xlist[vertex].use==0){
printf("该节点已被删除!!!");
return(-1);
}
ArcBox *p;
p = G.xlist[vertex].firstout;
while(p){
count++;
p = p->tlink;
}
return(count);
}
/************************************************************************/
/* 计算节点的入度 */
/************************************************************************/
int inDegree(OLGraph G, VertexType vex)
{
int count=0;
int vertex = LocateVex(G, vex);
if(G.xlist[vertex].use==0){
printf("该节点已被删除!!!");
return(-1);
}
ArcBox *p;
p = G.xlist[vertex].firstin;
while(p){
count++;
p = p->hlink;
}
return(count);
}
/************************************************************************/
/* 插入顶点 */
/************************************************************************/
bool InsertVex(OLGraph &G, VertexType vex){
if(G.length==MAX_VERTEX_NUM){
return false;
}else{
G.xlist[G.length].data=vex;
G.xlist[G.length].use=1;
G.xlist[G.length].firstin = G.xlist[G.length].firstout = NULL;
G.vexnum++;
G.length++;
return true;
}
}
/************************************************************************/
/* 插入弧 */
/************************************************************************/
bool InsertArc(OLGraph &G, VertexType vex1, VertexType vex2){
if ((G.xlist[LocateVex(G, vex1)].use==0)||(G.xlist[LocateVex(G, vex2)].use==0))
{
printf("要插入的弧对应的节点不存在!!!");
return false;
}
ArcBox *arcNode = (ArcBox *)malloc(sizeof(ArcBox));
if(!arcNode) exit(1);
arcNode->tailvex = LocateVex(G, vex1);
arcNode->headvex = LocateVex(G, vex2);
arcNode->tlink = G.xlist[arcNode->tailvex].firstout;
arcNode->hlink = G.xlist[arcNode->headvex].firstin;
G.xlist[arcNode->tailvex].firstout = G.xlist[arcNode->headvex].firstin = arcNode;
G.arcnum++;
return true;
}
/************************************************************************/
/* 删除弧 */
/************************************************************************/
bool DeleteArc(OLGraph &G, VertexType vex1, VertexType vex2){
if ((G.xlist[LocateVex(G, vex1)].use==0)||(G.xlist[LocateVex(G, vex2)].use==0))
{
printf("要删除的弧对应的节点不存在!!!");
return false;
}
ArcBox *arcNode1;
ArcBox *arcNode2;
arcNode1=G.xlist[LocateVex(G, vex1)].firstout;
if(arcNode1&&(arcNode1->tailvex==LocateVex(G, vex1))&&
(arcNode1->headvex==LocateVex(G, vex2)))
{
arcNode2=arcNode1;
G.xlist[LocateVex(G, vex1)].firstout=arcNode1->tlink;
}else{
while(arcNode1->tlink)
{
if((arcNode1->tlink->tailvex==LocateVex(G, vex1))&&
(arcNode1->tlink->headvex==LocateVex(G, vex2)))
{
arcNode2=arcNode1->tlink;
arcNode1->tlink=arcNode1->tlink->tlink;
}else
{
arcNode1=arcNode1->tlink;
}
}
}
arcNode1=G.xlist[LocateVex(G, vex2)].firstin;
if(arcNode1&&(arcNode1->tailvex==LocateVex(G, vex1))&&
(arcNode1->headvex==LocateVex(G, vex2)))
{
arcNode2=arcNode1;
G.xlist[LocateVex(G, vex2)].firstin=arcNode1->hlink;
}else{
while(arcNode1->hlink)
{
if((arcNode1->hlink->tailvex==LocateVex(G, vex1))&&
(arcNode1->hlink->headvex==LocateVex(G, vex2)))
{
arcNode2=arcNode1->hlink;
arcNode1->hlink=arcNode1->hlink->hlink;
}else{
arcNode1=arcNode1->hlink;
}
}
}
G.arcnum--;
free(arcNode2);
return true;
}
/************************************************************************/
/* 删除顶点 */
/************************************************************************/
bool DeleteVex(OLGraph &G, VertexType vex){
int x = LocateVex(G, vex);
ArcBox *arcNode1;
VertexType vex1;
arcNode1=G.xlist[x].firstout;
while(arcNode1){
vex1=G.xlist[arcNode1->headvex].data;
DeleteArc(G,vex,vex1);
arcNode1=G.xlist[x].firstout;
}
arcNode1=G.xlist[x].firstin;
while(arcNode1){
vex1=G.xlist[arcNode1->tailvex].data;
DeleteArc(G,vex1,vex);
arcNode1=G.xlist[x].firstin;
}
G.xlist[x].use=0;
G.vexnum--;
return true;
}
/************************************************************************/
/* 广度优先搜索—非连通图 */
/************************************************************************/
bool visited[MAX_VERTEX_NUM];
ArcBox *nextArc=NULL;
int firstAdjvex(OLGraph G, int ivex)
{
if(!G.xlist[ivex].firstout) return(-1);//无邻接点
nextArc = G.xlist[ivex].firstout->tlink;
return(G.xlist[ivex].firstout->headvex);
}
int nextAdjvex(OLGraph G)
{
if(!nextArc) return(-1);
int i = nextArc->headvex;
nextArc = nextArc->tlink;
return(i);
}
void BFSTraverse(OLGraph G){
LinkQueue Q;
for (int v=0; v<G.vexnum; ++v)
visited[v] = false; //初始化访问标志
InitQueue(Q); // 置空的辅助队列Q
for ( v=0; v<G.vexnum; ++v )
if ( !visited[v]) { // v 尚未访问
visited[v] = true;
printf("%c",G.xlist[v].data) ;
printf(" "); // 访问u
EnQueue(Q, v); // v入队列
while (!QueueEmpty(Q)) {
int u;
DeQueue(Q, u); // 队头元素出队并置为u
for(int w=firstAdjvex(G, u); w>=0; w=nextAdjvex(G))
if ( ! visited[w]) {
visited[w]=true;
printf("%c",G.xlist[w].data) ;
printf(" "); // 访问u
EnQueue(Q, w); // 访问的顶点w入队列
} // if
} // while
}
} // BFSTraverse
/************************************************************************/
/* 深度优先搜索—非连通图 */
/************************************************************************/
void DFS(OLGraph G, int v) {
// 从顶点v出发,深度优先搜索遍历连通图 G
visited[v] = true;
//cout<<G.xlist[v].data<<" ";
printf("%c",G.xlist[v].data);
printf(" ");
for(int w=firstAdjvex(G, v);w>=0; w=nextAdjvex(G))
if (!visited[w]) DFS(G, w);
// 对v的尚未访问的邻接顶点w递归调用DFS
}
void DFSTraverse(OLGraph G) {
for (int v=0; v<G.vexnum; ++v)
visited[v] = false; // 访问标志数组初始化
for (v=0; v<G.vexnum; ++v) {
if (!visited[v]) DFS(G, v); // 对尚未访问的顶点调用DFS
}
}
/************************************************************************/
/* 深度优先的生成树 */
/************************************************************************/
int FirstAdjvex(OLGraph G, int ivex)
{
nextArc=G.xlist[ivex].firstout;
b: if(!nextArc) return(-1);//无邻接点
int x = nextArc->headvex;
if(visited[x]){
nextArc=nextArc->tlink;
goto b;
}
nextArc = G.xlist[x].firstout;
return(x);
}
int NextAdjvex(OLGraph G){
a: if(!nextArc) return(-1);//无邻接点
int x = nextArc->headvex;
if(visited[x]) {
nextArc=nextArc->tlink;
goto a;
}
nextArc=G.xlist[x].firstout;
return(x);
}
void DFSTree(OLGraph G,int v, CSTree &T){
visited[v]=true;
bool first = true;
CSTree q;
for(int w =FirstAdjvex(G,v);w>=0;w=NextAdjvex(G))
{
if(!visited[w]){
CSTree p = (CSTree)malloc(sizeof(CSNode));
p->data=G.xlist[w].data;
p->firstchild=p->nextsibling=NULL;
if(first){
T->firstchild=p;
first=false;
}else{
q->nextsibling=p;
}
q=p;
DFSTree(G,w,q);
}
}
}
void DFSForset(OLGraph G,CSTree &T){
T=NULL;
CSTree q;
for (int v=0;v<G.vexnum;v++)
visited[v]=false;
for (v =0;v<G.vexnum;v++) {
if(!visited[v]){
CSTree p = (CSTree)malloc(sizeof(CSNode));
p->data=G.xlist[v].data;
p->firstchild=p->nextsibling=NULL;
if(!T){
T=p;
}else{
q->nextsibling=p;
}
q=p;
DFSTree(G,v,p);
}
}
}
/************************************************************************/
/* 孩子兄弟二叉树遍历 */
/************************************************************************/
void PreOrderTreeset(CSTree T){
if(T){
printf("%c",T->data);
printf(" ");
PreOrderTreeset(T->firstchild);
PreOrderTreeset(T->nextsibling);
}
}
/************************************************************************/
/* 关键路径 */
/************************************************************************/
int indegree[MAX_VERTEX_NUM];
int ve[MAX_VERTEX_NUM];
int vl[MAX_VERTEX_NUM];
SqStack T;
SqStack S;
bool TopologicalSort(OLGraph G,SqStack &T){
for(int i=0;i<G.vexnum;i++){
indegree[i]=inDegree(G,G.xlist[i].data);
}
InitStack(S);
for (i=0;i<G.vexnum;i++)
{
if(indegree[i]==0)
Push(S,i);
ve[i]=0;
}
int count=0;
int k;
while(!StackEmpty(S)){
Pop(S,i);
Push(T,i);
printf("%c",G.xlist[i].data);
count++;
ArcBox *p;
for(p=G.xlist[i].firstout;p;p=p->tlink){
k=p->headvex;
if(!(--indegree[k]))
Push(S,k);
if(ve[i]+p->weight>ve[k])
ve[k]=ve[i]+p->weight;
}
}
printf("/n");
if(count<G.vexnum)
return false;
return true;
}
void CriticalPath(OLGraph G){
int j,k,dut,ee,el;
char tag;
ArcBox *p;
InitStack(T);
if(!TopologicalSort(G,T)){
printf("该图存在环/n");
return;
}
for(int i=0;i<G.vexnum;i++){
vl[i]=ve[G.vexnum-1];
}
while(!(StackEmpty(T))){
for (Pop(T,j),Push(S,j),p=G.xlist[j].firstout;p;p=p->tlink) {
k=p->headvex;
dut=p->weight;
if(vl[k]-dut<vl[j]){
vl[j]=vl[k]-dut;
}
}
}
while (!StackEmpty(S)) {
Pop(S,i);
if(vl[i]==ve[i])
printf("%c",G.xlist[i].data);
}
}
//---------------------------------------------------------------------------------
OLGraph G;
ALGraph A;
VertexType e;
VertexType f;
CSTree t;
void out(){
for(int i = 0; i < G.length; i++){
if(G.xlist[i].use==0){
i++;
}
int din = inDegree(G, G.xlist[i].data);
int dout = outDegree(G, G.xlist[i].data);
printf("节点=%c 入度=%d 出度=%d/n", G.xlist[i].data,din,dout);
}
}
void Loop(OLGraph G){
for(int i=0;i<G.vexnum;i++){
indegree[i]=inDegree(G,G.xlist[i].data);
}
InitStack(S);
for (i=0;i<G.vexnum;i++)
{
if(indegree[i]==0)
Push(S,i);
}
int count=0;
int k;
while(!StackEmpty(S)){
Pop(S,i);
printf("%c",G.xlist[i].data);
count++;
ArcBox *p;
for(p=G.xlist[i].firstout;p;p=p->tlink){
k=p->headvex;
if(!(--indegree[k]))
Push(S,k);
}
}
printf("/n");
if(count<G.vexnum)
printf("该图存在回路/n");
else
printf("该图不存在回路/n");
}
int mune1(){
CreateOLGraph(G);
printf(" 创建有向图(十字链表)/n");
printf(" &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&/n");
printf(" & 命令菜单 &/n");
printf(" & -------------------------------- &/n");
printf(" & 1---求每个顶点的入度和出度 &/n");
printf(" & 2---插入顶点 &/n");
printf(" & 3---删除顶点 &/n");
printf(" & 4---插入弧 &/n");
printf(" & 5---删除弧 &/n");
printf(" & 0---返回上一层 &/n");
printf(" &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&/n");
A1: printf("请输入要选择的操作/n**");
int code1;
scanf("%d",&code1);
switch(code1){
case 1:
out();
break;
case 2:
printf("请输入要插入节点的值:/n");
fflush(stdin);
scanf("%c",&e);
InsertVex(G,e);
out();
break;
case 3:
printf("请输入要删除节点的值:/n");
fflush(stdin);
scanf("%c",&e);
DeleteVex(G,e);
out();
break;
case 4:
printf("请输入要插入的弧的起始点:/n");
fflush(stdin);
scanf("%c%c",&e,&f);
InsertArc(G,e,f);
out();
break;
case 5:
printf("请输入要删除的弧的起始点:/n");
fflush(stdin);
scanf("%c%c",&e,&f);
DeleteArc(G,e,f);
out();
break;
case 0:
return 0;
default:
printf("输入的指令有误!请重新输入:");
goto A1;
}
goto A1;
return 1;
};
int mune2(){
CreateALGraph(A);
printf(" 创建有向图(邻接矩阵)/n");
printf(" &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&/n");
printf(" & 命令菜单 &/n");
printf(" & -------------------------------- &/n");
printf(" & 1---转化为十字链表存储结构 &/n");
printf(" & 2---对深度优先生成森林进行遍历 &/n");
printf(" & 3---判断图中是否存在环 &/n");
printf(" & 4---顶点u到其余各点的最短路径 &/n");
printf(" & 5---任两个顶点之间的最短路径 &/n");
printf(" & 6---求关键路径 &/n");
printf(" & 0---返回上一层 &/n");
printf(" &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&/n");
A2: printf("请输入要选择的操作/n**");
int code2;
scanf("%d",&code2);
switch(code2){
case 1:
Convert(A,G);
out();
break;
case 2:
DFSForset(G,t);
PreOrderTreeset(t);
printf("/n");
break;
case 3:
Loop(G);
break;
case 4:
char in;
printf("请输入要顶点v:/n");
fflush(stdin);
scanf("%c",&in);
ShortestPath_DIJ(A,LocateVex(A,in));
printPath(A,LocateVex(A,in));
break;
case 5:
AllShortestPath(A);
break;
case 6:
CriticalPath(G);
break;
case 0:
return 0;
default:
printf("输入的指令有误!请重新输入:");
goto A2;
}
goto A2;
return 1;
};
int main(int argc, char* argv[])
{
main: printf(" 数据结构课程设计/n");
printf(" &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&/n");
printf(" & 命令菜单 &/n");
printf(" & -------------------------------- &/n");
printf(" & 1--创建有向图(十字链表) &/n");
printf(" & 2--创建有向图(邻接矩阵) &/n");
printf(" & 0--------退出 &/n");
printf(" &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&/n");
printf("请输入要选择的操作/n**");
int code;
A: scanf("%d",&code);
switch(code){
case 1:
if(mune1()==0)
goto main;
break;
case 2:
if(mune2()==0)
goto main;
break;
case 0:
return 0;
default:
printf("输入的指令有误!请重新输入:");
goto A;
}
return 0;
}