QQ登录

只需一步,快速开始

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 1078|回复: 12

不好意思。关于图的拓补排序问题,谢谢

[复制链接]
发表于 2004-6-8 23:01:47 | 显示全部楼层 |阅读模式
编译成功,但运行结果不是期望的。
[code:1]
#include <stdio.h>
#define vnum 20

typedef struct arcnode
{
  int adjvex;
  int info;
  struct arcnode *nextarc;
} ArcNodeTp;

typedef struct vexnode
{
  int vertex;
  int in;
  ArcNodeTp *firstarc;
} AdjList[vnum];

typedef struct linkgraph
{
  AdjList adjs;
  int vexnum, arcnum;
} LGraphTp;

typedef struct node
{
  int data;
  struct node *next;
} LStackTp;


LGraphTp* Create_LNvGraphP (LGraphTp *ga);

int main (void)
{
  LGraphTp *ga;
  ga = (LGraphTp *) malloc (sizeof(LGraphTp));

  printf("\n有向图\n");
  ga = Create_LNvGraphP(ga);
  Print_LinkList(ga);
  Top_Sort(ga);

}

LGraphTp* Create_LNvGraphP (LGraphTp *ga)
{
  ArcNodeTp *p;
  int vex, arc, vexs, arcnum;
  int i, j, k;

  printf("请输入顶点个数:");
  scanf("%d", &vex);
  printf("请输入边数个数:");
  scanf("%d", &arc);
  ga -> vexnum = vex;
  ga -> arcnum = arc;

  for (i = 0; i < vex; i++)
    {
      ga -> adjs[i].vertex = i + 1;
      ga -> adjs[i].firstarc = NULL;
    }

  for (k = 0; k < arc; k++)
    {
      printf("请输入第%d条边的起始编号和终点编号:", k + 1);
      scanf("%d %d", &i, &j);
      p = (ArcNodeTp *) malloc (sizeof(ArcNodeTp));
      p -> adjvex = j;
      p -> nextarc = ga -> adjs[i - 1].firstarc;
      ga -> adjs[i - 1].firstarc = p;
    }
  return (ga);
}

int Print_LinkList (LGraphTp *ga)
{
  ArcNodeTp *p;
  int k;
  printf("\n目前输入的邻接表为:\n\n");

  for (k = 0; k < ga -> vexnum; k++)
    {
      printf("V%d:%d |", k + 1, ga -> adjs[k].vertex);
      p = ga -> adjs[k].firstarc;
      while (p != NULL)
        {
          printf(" -> %d", p -> adjvex);
          p = p -> nextarc;
        }
      printf("\n\n");
    }
}

int InitStack(LStackTp **ls)
{
  *ls = NULL;
}

int Push(LStackTp **ls, int x)
{
  LStackTp *p;
  p = (LStackTp *) malloc (sizeof(LStackTp));
  p -> data = x;
  p -> next = *ls;
  *ls = p;
}

int Pop(LStackTp **ls, int *x)
{
  LStackTp *p;
  if (*ls != NULL)
    {
      p = *ls;
      *x = p -> data;
      *ls = (*ls) -> next;
      free(p);
      return 1;
    }
  else
    return 0;
}

int EmptyStack(LStackTp **ls)
{
  if (*ls == NULL)
    return (1);
  else
    return (0);
}

int GetTop(LStackTp **ls , int *x)
{
  if (*ls != NULL)
    {
      *x = (*ls) -> data;
      return 1;
    }
  else
    return 0;
}

int Top_Sort (LGraphTp *ga)
{
  LStackTp *S;
  ArcNodeTp *p;
  int count, i, v;
  InitStack(&S);

  for (i = 0; i < ga -> vexnum; i ++)
    {
      if (ga -> adjs[i].in == 0)
        Push(&S,i);
    }
  count = 0;
  while (! EmptyStack(&S))
    {
      Pop (&S, &v);
      printf("%d ", v);
      count ++;
      p = ga -> adjs[i].firstarc;
      
      while (p != NULL)
        {
          (ga -> adjs[p -> adjvex].in) --;
          if (ga -> adjs[p -> adjvex].in == 0)
            Push(&S, p -> adjvex);
          p = p -> nextarc;
        }
    }
  if (count < ga -> vexnum)
    {
      printf("\n图中有环!\n");
      return 0;
    }
  else
    return 1;
}
[/code:1]
发表于 2004-6-8 23:35:24 | 显示全部楼层
[code:1]
有向图
请输入顶点个数:4
请输入边数个数:3
请输入第1条边的起始编号和终点编号:1 2
请输入第2条边的起始编号和终点编号:2 4
请输入第3条边的起始编号和终点编号:1 3

目前输入的邻接表为:

V1:1 | -> 3 -> 2

V2:2 | -> 4

V3:3 |

V4:4 |

3 2 1 0
[/code:1]
结果是不是这样?你想的结果是什么样的啊。
回复

使用道具 举报

 楼主| 发表于 2004-6-8 23:56:10 | 显示全部楼层
[quote:6efb52ccf7="sagaeon"][code:1]
有向图
请输入顶点个数:4
请输入边数个数:3
请输入第1条边的起始编号和终点编号:1 2
请输入第2条边的起始编号和终点编号:2 4
请输入第3条边的起始编号和终点编号:1 3

目前输入的邻接表为:

V1:1 | -> 3 -> 2

V2:2 | -> 4

V3:3 |

V4:4 |

3 2 1 0
[/code:1]
结果是不是这样?你想的结果是什么样的啊。[/quote]
根据你输入的,正确应该是:
1 -> 3 -> 2 -> 4

1 -> 2 -> 4 -> 3
三个答案其中一种。
(程序却是 3 -> 2 -> 1 -> 0)
回复

使用道具 举报

 楼主| 发表于 2004-6-9 00:04:34 | 显示全部楼层
图示:

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
回复

使用道具 举报

发表于 2004-6-9 00:18:27 | 显示全部楼层
lluct, 你的图是用鼠标“手绘”的吧?建议用xfig来画图……
回复

使用道具 举报

 楼主| 发表于 2004-6-9 00:22:03 | 显示全部楼层
[quote:516959e58f="sjinny"]lluct, 你的图是用鼠标“手绘”的吧?建议用xfig来画图…… [/quote] 早讲阿。
回复

使用道具 举报

发表于 2004-6-9 11:02:07 | 显示全部楼层
明白了,再看看。
回复

使用道具 举报

发表于 2004-6-9 11:38:49 | 显示全部楼层
你这个域没有初始化
ga -> adjs.in
应该在创建图得时候就把入度给初始化了
回复

使用道具 举报

发表于 2004-6-9 11:56:30 | 显示全部楼层
有几个地方错了
[code:1]
int Top_Sort (LGraphTp *ga)
{
  LStackTp *S;
  ArcNodeTp *p;
  int count, i, v;
  InitStack(&S);

  for (i = 0; i < ga -> vexnum; i ++)
    {
      if (ga -> adjs[i].in == 0)
   Push(&S,i);
    }
  count = 0;
  while (! EmptyStack(&S))
    {
      Pop (&S, &v);
      printf("%d ", v);//这里应该是v+1
      count ++;
      p = ga -> adjs[i].firstarc; //这里应该是p = ga->adjs[v].firstarc;
      
      while (p != NULL)
   {
     (ga -> adjs[p -> adjvex].in) --; //应该是(ga -> adjs[p -> adjvex-1].in) --;
   if (ga -> adjs[p -> adjvex].in == 0) //这里同上
       Push(&S, p -> adjvex); //同上
     p = p -> nextarc;
   }
    }
  if (count < ga -> vexnum)
    {
      printf("\n图中有环!\n");
      return 0;
    }
  else
    return 1;
}
[/code:1]
回复

使用道具 举报

 楼主| 发表于 2004-6-9 13:15:30 | 显示全部楼层
[quote:f1760da3fc="quarkonics"]有几个地方错了
[code:1]
int Top_Sort (LGraphTp *ga)
{
  LStackTp *S;
  ArcNodeTp *p;
  int count, i, v;
  InitStack(&S);

  for (i = 0; i < ga -> vexnum; i ++)
    {
      if (ga -> adjs[i].in == 0)
   Push(&S,i);
    }
  count = 0;
  while (! EmptyStack(&S))
    {
      Pop (&S, &v);
      printf("%d ", v);//这里应该是v+1
      count ++;
      p = ga -> adjs[i].firstarc; //这里应该是p = ga->adjs[v].firstarc;
      
      while (p != NULL)
   {
     (ga -> adjs[p -> adjvex].in) --; //应该是(ga -> adjs[p -> adjvex-1].in) --;
   if (ga -> adjs[p -> adjvex].in == 0) //这里同上
       Push(&S, p -> adjvex); //同上
     p = p -> nextarc;
   }
    }
  if (count < ga -> vexnum)
    {
      printf("\n图中有环!\n");
      return 0;
    }
  else
    return 1;
}
[/code:1][/quote]
不行阿。结点编号还是按顺序倒序输出。我在看看。
回复

使用道具 举报

发表于 2004-6-9 13:16:04 | 显示全部楼层
[quote:c9b9014fbf="quarkonics"]你这个域没有初始化
ga -> adjs.in
应该在创建图得时候就把入度给初始化了[/quote]
对啊,是不是该这样:[code:1]
LGraphTp* Create_LNvGraphP (LGraphTp *ga)
{
  ArcNodeTp *p;
  int vex, arc, vexs, arcnum;
  int i, j, k;
   
  printf("请输入顶点个数:");
  scanf("%d", &vex);
  printf("请输入边数个数:");
  scanf("%d", &arc);
  ga -> vexnum = vex;
  ga -> arcnum = arc;

  for (i = 0; i < vex; i++)
    {
      ga -> adjs[i].vertex = i + 1;
      ga -> adjs[i].firstarc = NULL;
      ga -> adjs[i].in =0;//加加加~~~~~~~~~
    }

  for (k = 0; k < arc; k++)
    {
      printf("请输入第%d条边的起始编号和终点编号:", k + 1);
      scanf("%d %d", &i, &j);
      p = (ArcNodeTp *) malloc (sizeof(ArcNodeTp));
      p -> adjvex = j;
      p -> nextarc = ga -> adjs[i-1 ].firstarc;
      ga -> adjs[i-1 ].firstarc = p;
      ga->adjs[j-1].in= ga->adjs[j-1].in+1;//加加加~~~~~~~~
    }
  return (ga);
}[/code:1]
并且加上quarkonics兄的修改。
回复

使用道具 举报

发表于 2004-6-9 14:43:50 | 显示全部楼层
就是这样得
回复

使用道具 举报

 楼主| 发表于 2004-6-9 16:53:24 | 显示全部楼层
谢谢你们阿。 在一个初学且教科书上只有伪代码(且错漏百出)的情况下。没有你们的帮助,我看我要绕很多弯才能弄明白。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

GMT+8, 2024-11-8 04:48 , Processed in 0.049680 second(s), 17 queries .

© 2021 Powered by Discuz! X3.5.

快速回复 返回顶部 返回列表