8_6.C
上传用户:wyn840322
上传日期:2007-01-13
资源大小:294k
文件大小:7k
源码类别:

数据结构

开发平台:

C/C++

  1. /* ======================================== */
  2. /*    程式实例: 8_6.c                       */
  3. /*    使用拓扑排序来找图回路              */
  4. /* ======================================== */
  5. #include <stdlib.h>
  6. #define MAXQUEUE 20               /* 伫列的最大容量       */
  7. struct node                       /* 图顶点结构宣告     */
  8. {
  9.    int vertex;                    /* 顶点资料             */
  10.    struct node *nextnode;         /* 指下一顶点的指标     */
  11. };
  12. typedef struct node *graph;       /* 图的结构新型态     */
  13. struct node head1[8];             /* 图顶点结构数组     */
  14. struct node head2[8];             /* 图顶点结构数组     */
  15. int queue[MAXQUEUE];              /* 伫列的数组宣告       */
  16. int front = -1;                   /* 伫列的前端           */
  17. int rear = -1;                    /* 伫列的后端           */
  18. /* ---------------------------------------- */
  19. /*  建立含分支度的图                      */
  20. /* ---------------------------------------- */
  21. void creategraph(graph head,int *node,int num)
  22. {
  23.    graph newnode;                 /* 新顶点指标           */
  24.    graph ptr;
  25.    int from;                      /* 边线的起点           */
  26.    int to;                        /* 边线的终点           */
  27.    int i;
  28.    for ( i = 0; i < num; i++ )    /* 读取边线的回路       */
  29.    {
  30.       from = node[i*2];           /* 边线的起点           */
  31.       to = node[i*2+1];           /* 边线的终点           */
  32.       head[to].vertex += 1;       /* 内分支度加一         */
  33.       /* 建立新顶点记忆体 */
  34.       newnode = ( graph ) malloc(sizeof(struct node));
  35.       newnode->vertex = to;       /* 建立顶点内容         */
  36.       newnode->nextnode = NULL;   /* 设定指标初值         */
  37.       ptr = &(head[from]);        /* 顶点位置             */
  38.       while ( ptr->nextnode != NULL ) /* 遍历至链表尾     */
  39.          ptr = ptr->nextnode;     /* 下一个顶点           */
  40.       ptr->nextnode = newnode;    /* 插入结尾             */
  41.    }
  42. }
  43. /* ---------------------------------------- */
  44. /*  图的拓扑排序                          */
  45. /* ---------------------------------------- */
  46. int toposort(graph head,int num)
  47. {
  48.    graph ptr;
  49.    int i;
  50.    /* 将内分支度为零页的顶点存入伫列的回路 */
  51.    for ( i = 1; i <= num; i++ )
  52.       if ( head[i].vertex == 0 )  /* 如果分支度是零       */
  53.          enqueue(i);              /* 存顶点至伫列         */
  54.    while ( ( i = dequeue() ) != -1 )
  55.    {
  56.       printf(" %d ",i);           /* 印出拓扑排序顶点     */
  57.       ptr = head[i].nextnode;     /* 顶点位置             */
  58.       while ( ptr != NULL )       /* 遍历至链表尾         */
  59.       {
  60.          i = ptr->vertex;         /* 得到顶点值           */
  61.          head[i].vertex --;       /* 顶点内分支度减一     */
  62.          if ( head[i].vertex == 0  )  /* 如果内分支度是零 */
  63.             enqueue(i);           /* 存顶点至伫列         */
  64.          ptr = ptr->nextnode;     /* 下一个顶点           */
  65.       }
  66.    }
  67.    printf("n");                  /* 换行                 */
  68.    for ( i = 1; i <= num; i++ )   /* 检查是否有回路       */
  69.       if ( head[i].vertex != 0 )  /* 内分支度不是零       */
  70.          return 1;                /* 有回路               */
  71.    return 0;                      /* 没有回路             */
  72. }
  73. /* ---------------------------------------- */
  74. /*  伫列资料的存入                          */
  75. /* ---------------------------------------- */
  76. int enqueue(int value)
  77. {
  78.    if ( rear + 1 == front ||      /* 检查伫列是否全满     */
  79.         (rear == (MAXQUEUE - 1) && front <= 0) )
  80.       return -1;                  /* 无法存入             */
  81.    rear++;                        /* 后端指标往前移       */
  82.    if ( rear == MAXQUEUE )        /* 是否超过界限         */
  83.       rear = 0;                   /* 从头开始             */
  84.    queue[rear] = value;           /* 存入伫列             */
  85. }
  86. /* ---------------------------------------- */
  87. /*  伫列资料的取出                          */
  88. /* ---------------------------------------- */
  89. int dequeue()
  90. {
  91.    if ( front  == rear )          /* 检查伫列是否是空     */
  92.       return -1;                  /* 无法取出             */
  93.    front++;                       /* 前端指标往前移       */
  94.    if ( front == MAXQUEUE )       /* 是否超过界限         */
  95.       front = 0;                  /* 从头开始             */
  96.    return queue[front];           /* 伫列取出             */
  97. }
  98. /* ---------------------------------------- */
  99. /*  主程式: 建立图后,找寻图内是否有回路.  */
  100. /* ---------------------------------------- */
  101. void main()
  102. {
  103.    graph ptr;
  104.    int node[10][2] = { {3, 2},    /* 边线数组             */
  105.                        {2, 1},
  106.                        {2, 5},
  107.                        {2, 6},
  108.                        {1, 4},
  109.                        {5, 4},
  110.                        {7, 4},
  111.                        {6, 7},
  112.                        {5, 6},
  113.                        {7, 5} };
  114.    int i;
  115.    for ( i = 1; i <= 7; i++ )
  116.    {
  117.       head1[i].vertex = 0;        /* 设定顶点值           */
  118.       head1[i].nextnode = NULL;   /* 清除图1指标        */
  119.       head2[i].vertex = 0;        /* 设定顶点值           */
  120.       head2[i].nextnode = NULL;   /* 清除图2指标        */
  121.    }
  122.    creategraph(head1,node,8);     /* 建立图1            */
  123.    creategraph(head2,node,10);    /* 建立图2            */
  124.    printf("图1 - 含入度的邻接表内容:n");
  125.    for ( i = 1; i <= 7; i++ )
  126.    {
  127.       printf("顶点%d(%d) =>",i,head1[i].vertex);
  128.       ptr = head1[i].nextnode;    /* 顶点位置             */
  129.       while ( ptr != NULL )       /* 遍历至链表尾         */
  130.       {
  131.          printf(" %d ",ptr->vertex);  /* 印出顶点内容     */
  132.          ptr = ptr->nextnode;     /* 下一个顶点           */
  133.       }
  134.       printf("n");               /* 换行                 */
  135.    }
  136.    printf("图1 - 拓扑排序的内容:n");
  137.    if ( toposort(head1,7) )       /* 拓扑排序             */
  138.       printf("图有回路n");
  139.    else
  140.       printf("图没有回路n");
  141.    front = rear = -1;             /* 清除伫列             */
  142.    printf("n图2 - 含入度的邻接表内容:n");
  143.    for ( i = 1; i <= 7; i++ )
  144.    {
  145.       printf("顶点%d(%d) =>",i,head2[i].vertex);
  146.       ptr = head2[i].nextnode;    /* 顶点位置             */
  147.       while ( ptr != NULL )       /* 遍历至链表尾         */
  148.       {
  149.          printf(" %d ",ptr->vertex);  /* 印出顶点内容     */
  150.          ptr = ptr->nextnode;     /* 下一个顶点           */
  151.       }
  152.       printf("n");               /* 换行                 */
  153.    }
  154.    printf("图2 - 拓扑排序的内容:n");
  155.    if ( toposort(head2,7) )       /* 拓扑排序             */
  156.       printf("图有回路n");
  157.    else
  158.       printf("图没有回路n");
  159. }