图--拓扑排序

 

在拓扑排序算法中,使用一个存放入度为零的顶点的链式栈,供选择和输出无前驱的顶点。只要出现入度为零的顶点,就将它加入栈中。
使用这种栈的拓扑排序算法可以描述如下:
(1) 建立入度为零的顶点栈;
(2) 当入度为零的顶点栈不空时, 重复执行
从顶点栈中退出一个顶点, 并输出之;
从AOV网络中删去这个顶点和它发出的边, 边的终顶点入度减一;
如果边的终顶点入度减至0, 则该顶点进入度为零的顶点栈;
(3) 如果输出顶点个数少于AOV网络的顶点个数, 则报告网络中存在有向环。
在算法实现时,为了建立入度为零的顶点栈,可以不另外分配存储空间,直接利用入度为零的顶点的indegree[ ]数组元素。我们设立了一个栈顶指针top,指示当前栈顶的位置,即某一个入度为零的顶点位置。
栈初始化时置top = -1,表示空栈。
将顶点 i 进栈时,执行以下指针的修改:
indegree[i] = top;  top = i; // top指向新栈顶i, 原栈顶元素放在indegree[i]中
退栈操作可以写成:
j = top;  top = indegree[top];   
//位于栈顶的顶点的位置记于 j, top退到次栈顶
(这个算法很好,但是不便于理解,所以又多写了一段直接用栈的~)
//以下是代码
#include <iostream>
#include <stack>
using namespace std;

#define MAX_VERTEX_NUM 100
using namespace std;
typedef char v_type;   //定点的数据类型
typedef struct ArcNode {  
 int adjvex;
 struct ArcNode *nextarc;
 int weight;
}ArcNode;

typedef struct VNode {   //边结点
 v_type data;
 int indegree;   //加入入度
 ArcNode *firstarc;
}VNode,AdjList[MAX_VERTEX_NUM];

typedef struct {
 AdjList vexs;
 int vexnum,arcnum;
}ALGraph;

//------------------位置确定函数---------------------
//用来确定u所处的位置

int LocateVex(ALGraph G, v_type u) {
 int i;
 for (i=0; i<G.vexnum; i++) {
  if (u==G.vexs[i].data) return i;
 }
 if (i==G.vexnum) {
  cout << "Error!" ;
  exit (1);
 }
}

//---------------creat graph------------------
void CreatALGraph(ALGraph &G) {
 int i,j,k,w;
 ArcNode *p;
 v_type v1,v2;
 cout << "Input vexnum & arcnum:" ;
 cin >> G.vexnum >> G.arcnum;
 cout << "Input vertices" ;
 for (i=0; i<G.vexnum; i++) {  //初始化
  cin >> G.vexs[i].data ;
  G.vexs[i].indegree = 0;
  G.vexs[i].firstarc = NULL;
 }
 for (k=0; k<G.arcnum; k++) {
  cout << "Input arcs(v1, v2 & w):" ;
  cin >> v1 >> v2 >> w ;
  i = LocateVex(G, v1);
  j = LocateVex(G, v2);
  p = (ArcNode*)malloc(sizeof(ArcNode));
  p->adjvex = j;
  p->nextarc = G.vexs[i].firstarc;
  p->weight = w;
  G.vexs[i].firstarc = p;
  ++G.vexs[j].indegree;  //每次都增加一个入度
 }
}

//-------------top logical sort---------------------
//拓扑排序函数
bool TopLogicalSort(ALGraph G) {
 ArcNode *p;
 int i,k;
 int top = -1;  //虚拟栈顶
 int count = 0;  //用来计有多少个顶点访问到了
 for (i=0; i<G.vexnum; i++) {  //把入度为0的顶点入栈 
  if (G.vexs[i].indegree == 0) {
   G.vexs[i].indegree = top;
   top = i;
  }
 }
 while (top+1) {  //栈不为空时执行
  i = top;
  top = G.vexs[i].indegree;
  cout << G.vexs[i].data << ' ';  //访问当前顶点
  count++;
  for (p=G.vexs[i].firstarc; p; p=p->nextarc) {
   //对以该顶点为尾的弧的头顶点进行处理
   //每个都入度-1

   k = p->adjvex;
   G.vexs[k].indegree--;
   
   //如果这些后续顶点中经过入度-1后有的入度为0
   //那么这些顶点也入栈

   if (G.vexs[k].indegree==0) {
    G.vexs[k].indegree = top;
    top = k;
   }
  }
 }
 cout << endl;
 //如果访问的顶点小于全部顶点数,那么说明有环
 if (count<G.vexnum) return false; 
 else return true;
}
/*
//-----------------top logical sort 2------------------
bool TopLogicalSort(ALGraph G) {
 ArcNode *p;
 int i,k;
 stack<int> elem;
 int count = 0;
 for (i=0; i<G.vexnum; i++) {
  if (G.vexs[i].indegree==0) {
   elem.push(i);  //入栈
  }
 }
 while (!elem.empty()) {
  i = elem.top();  //弹出栈顶元素
  elem.pop();
  cout << G.vexs[i].data << ' ' ;
  ++count;
  for (p=G.vexs[i].firstarc; p; p=p->nextarc) {
   k = p->adjvex;
   G.vexs[k].indegree--;
   if (G.vexs[k].indegree==0) {
    elem.push(k);
   }
  }
 }
 cout << endl;
 
 if (count<G.vexnum) return false;
 else return true;
}*/
//------------------------judge-------------------------
void LogicalJudge(ALGraph G) {
 
 if (TopLogicalSort(G))
  cout << "It is a directed acycline graph!" << endl;
 else
  cout << "It is not a directed acycline graph!" << endl;
}
//-------------------main-------------------------------
int main() {
 ALGraph G;
 cout << "You must input a directed graph!" << endl;
 CreatALGraph(G);
 LogicalJudge(G);
 system("pause");
 return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值