⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 1-103.c

📁 1.7.1 图的邻接矩阵存储表示 311 范例1-102 图的邻接矩阵存储表示 ∷相关函数:CreateFAG函数 CreateDG函数 1.7.2 图的邻接表存储表示 324 范例1-10
💻 C
📖 第 1 页 / 共 2 页
字号:
Status DeleteArc(ALGraph *G,VertexType v,VertexType w)
{ /* 初始条件: 图G存在,v和w是G中两个顶点 */
  /* 操作结果: 在G中删除弧<v,w>,若G是无向的,则还删除对称弧<w,v> */
  ArcNode *p,*q;
  int i,j;
  i=LocateVex(*G,v); /* i是顶点v(弧尾)的序号 */
  j=LocateVex(*G,w); /* j是顶点w(弧头)的序号 */
  if(i<0||j<0||i==j)
    return ERROR;
  p=(*G).vertices[i].firstarc; /* p指向顶点v的第一条出弧 */
  while(p&&p->adjvex!=j) /* p不空且所指之弧不是待删除弧<v,w> */
  { /* p指向下一条弧 */
    q=p;
    p=p->nextarc;
  }
  if(p&&p->adjvex==j) /* 找到弧<v,w> */
  {
    if(p==(*G).vertices[i].firstarc) /* p所指是第1条弧 */
      (*G).vertices[i].firstarc=p->nextarc; /* 指向下一条弧 */
    else
      q->nextarc=p->nextarc; /* 指向下一条弧 */
    if((*G).kind%2) /* 网 */
      free(p->info);
    free(p); /* 释放此结点 */
    (*G).arcnum--; /* 弧或边数减1 */
  }
  if((*G).kind>=2) /* 无向,删除对称弧<w,v> */
  {
    p=(*G).vertices[j].firstarc; /* p指隙サ鉾的第一条出弧 */
    while(p&&p->adjvex!=i) /* p不空且所指之弧不是待删除弧<w,v> */
    { /* p指向下一条弧 */
      q=p;
      p=p->nextarc;
    }
    if(p&&p->adjvex==i) /* 找到弧<w,v> */
    {
      if(p==(*G).vertices[j].firstarc) /* p所指是第1条弧 */
        (*G).vertices[j].firstarc=p->nextarc; /* 指向下一条弧 */
      else
        q->nextarc=p->nextarc; /* 指向下一条弧 */
      if((*G).kind==3) /* 无向网 */
        free(p->info);
      free(p); /* 释放此结点 */
    }
  }
  return OK;
}
Boolean visited[MAX_VERTEX_NUM]; /* 访问标志数组(全局量) */
void(*VisitFunc)(char* v); /* 函数变量(全局量) */
void DFS(ALGraph G,int v)
{ /* 从第v个顶点出发递归地深度优先遍历图G。*/
  int w;
  VertexType v1,w1;
  strcpy(v1,*GetVex(G,v));
  visited[v]=TRUE; /* 设置访问标志为TRUE(已访问) */
  VisitFunc(G.vertices[v].data); /* 访问第v个顶点 */
  for(w=FirstAdjVex(G,v1);w>=0;w=NextAdjVex(G,v1,strcpy(w1,*GetVex(G,w))))
    if(!visited[w])
      DFS(G,w); /* 对v的尚未访问的邻接点w递归调用DFS */
}
void DFSTraverse(ALGraph G,void(*Visit)(char*))
{ /* 对图G作深度优先遍历。*/
  int v;
  VisitFunc=Visit; /* 使用全局变量VisitFunc,使DFS不必设函数指针参数 */
  for(v=0;v<G.vexnum;v++)
    visited[v]=FALSE; /* 访问标志数组初始化 */
  for(v=0;v<G.vexnum;v++)
    if(!visited[v])
      DFS(G,v); /* 对尚未访问的顶点调用DFS */
  printf("\n");
}
typedef int QElemType; /* 队列类型 */
typedef struct QNode
{
  QElemType data;
  struct QNode *next;
}QNode,*QueuePtr;
typedef struct
{
  QueuePtr front,rear; /* 队头、队尾指针 */
}LinkQueue;
Status InitQueue(LinkQueue *Q)
{ /* 构造一个空队列Q */
  (*Q).front=(*Q).rear=(QueuePtr)malloc(sizeof(QNode));
  if(!(*Q).front)
    exit(OVERFLOW);
  (*Q).front->next=NULL;
  return OK;
}
Status QueueEmpty(LinkQueue Q)
{ /* 若Q为空队列,则返回TRUE,否则返回FALSE */
  if(Q.front==Q.rear)
    return TRUE;
  else
    return FALSE;
}
Status EnQueue(LinkQueue *Q,QElemType e)
{ /* 插入元素e为Q的新的队尾元素 */
  QueuePtr 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)
{ /* 若队列不空,删除Q的队头元素,用e返回其值,并返回OK,否则返回ERROR */
  QueuePtr p;
  if((*Q).front==(*Q).rear)
    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 BFSTraverse(ALGraph G,void(*Visit)(char*))
{/*按广度优先非递归遍历图G。使用辅助队列Q和访问标志数组visited。*/
  int v,u,w;
  VertexType u1,w1;
  LinkQueue Q;
  for(v=0;v<G.vexnum;++v)
    visited[v]=FALSE; /* 置初值 */
  InitQueue(&Q); /* 置空的辅助队列Q */
  for(v=0;v<G.vexnum;v++) /* 如果是连通图,只v=0就遍历全图 */
    if(!visited[v]) /* v尚未访问 */
    {
      visited[v]=TRUE;
      Visit(G.vertices[v].data);
      EnQueue(&Q,v); /* v入队列 */
      while(!QueueEmpty(Q)) /* 队列不空 */
      {
        DeQueue(&Q,&u); /* 队头元素出队并置为u */
        strcpy(u1,*GetVex(G,u));
        for(w=FirstAdjVex(G,u1);w>=0;w=NextAdjVex(G,u1,strcpy(w1,*GetVex(G,w))))
          if(!visited[w]) /* w为u的尚未访问的邻接顶点 */
          {
            visited[w]=TRUE;
            Visit(G.vertices[w].data);
            EnQueue(&Q,w); /* w入队 */
          }
      }
    }
  printf("\n");
}
void Display(ALGraph G)
{ /* 输出图的邻接矩阵G */
  int i;
  ArcNode *p;
  switch(G.kind)
  {
    case DG: printf("有向图\n");
             break;
    case DN: printf("有向网\n");
             break;
    case AG: printf("无向图\n");
             break;
    case AN: printf("无向网\n");
  }
  printf("%d个顶点:\n",G.vexnum);
  for(i=0;i<G.vexnum;++i)
    printf("%s ",G.vertices[i].data);
  printf("\n%d条弧(边):\n",G.arcnum);
  for(i=0;i<G.vexnum;i++)
  {
    p=G.vertices[i].firstarc;
    while(p)
    {
      if(G.kind<=1) /* 有向 */
      {
        printf("%s→%s ",G.vertices[i].data,G.vertices[p->adjvex].data);
        if(G.kind==DN) /* 网 */
          printf(":%d ",*(p->info));
      }
      else /* 无向(避免输出两次) */
      {
        if(i<p->adjvex)
        {
          printf("%s-%s ",G.vertices[i].data,G.vertices[p->adjvex].data);
          if(G.kind==AN) /* 网 */
            printf(":%d ",*(p->info));
        }
      }
      p=p->nextarc;
    }
    printf("\n");
  }
}
void print(char *i)
{
  printf("%s ",i);
}
void main()
{
  int i,j,k,n;
  ALGraph g;
  VertexType v1,v2;
  printf("请选择有向图\n");
  CreateGraph(&g);
  Display(g);
  printf("删除一条边或弧,请输入待删除边或弧的弧尾 弧头:");
  scanf("%s%s",v1,v2);
  DeleteArc(&g,v1,v2);
  printf("修改顶点的值,请输入原值 新值: ");
  scanf("%s%s",v1,v2);
  PutVex(&g,v1,v2);
  printf("插入新顶点,请输入顶点的值: ");
  scanf("%s",v1);
  InsertVex(&g,v1);
  printf("插入与新顶点有关的弧或边,请输入弧或边数: ");
  scanf("%d",&n);
  for(k=0;k<n;k++)
  {
    printf("请输入另一顶点的值: ");
    scanf("%s",v2);
    printf("对于有向图,请输入另一顶点的方向(0:弧头 1:弧尾): ");
    scanf("%d",&j);
    if(j)
      InsertArc(&g,v2,v1);
    else
      InsertArc(&g,v1,v2);
  }
  Display(g);
  printf("删除顶点及相关的弧或边,请输入顶点的值: ");
  scanf("%s",v1);
  DeleteVex(&g,v1);
  Display(g);
  printf("深度优先搜索的结果:\n");
  DFSTraverse(g,print);
  printf("广度优先搜索的结果:\n");
  BFSTraverse(g,print);
  DestroyGraph(&g);
  printf("请顺序选择有向网,无向图,无向网\n");
  for(i=0;i<3;i++) /* 验证另外3种情况 */
  {
    CreateGraph(&g);
    Display(g);
    printf("插入新顶点,请输入顶点的值: ");
    scanf("%s",v1);
    InsertVex(&g,v1);
    printf("插入与新顶点有关的弧或边,请输入弧或边数: ");
    scanf("%d",&n);
    for(k=0;k<n;k++)
    {
      printf("请输入另一顶点的值: ");
      scanf("%s",v2);
      if(g.kind<=1) /* 有向 */
      {
        printf("对于有向图或网,请输入另一顶点的方向(0:弧头 1:弧尾): ");
        scanf("%d",&j);
        if(j)
          InsertArc(&g,v2,v1);
        else
          InsertArc(&g,v1,v2);
      }
      else /* 无向 */
        InsertArc(&g,v1,v2);
    }
    Display(g);
    printf("删除顶点及相关的弧或边,请输入顶点的值: ");
    scanf("%s",v1);
    DeleteVex(&g,v1);
    Display(g);
    DestroyGraph(&g);
  }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -