十字链表 邻接表实现各种操作

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

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值