在拓扑排序算法中,使用一个存放入度为零的顶点的链式栈,供选择和输出无前驱的顶点。只要出现入度为零的顶点,就将它加入栈中。
使用这种栈的拓扑排序算法可以描述如下:
(1) 建立入度为零的顶点栈;
(2) 当入度为零的顶点栈不空时, 重复执行
从顶点栈中退出一个顶点, 并输出之;
从AOV网络中删去这个顶点和它发出的边, 边的终顶点入度减一;
如果边的终顶点入度减至0, 则该顶点进入度为零的顶点栈;
(3) 如果输出顶点个数少于AOV网络的顶点个数, 则报告网络中存在有向环。
使用这种栈的拓扑排序算法可以描述如下:
(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退到次栈顶
栈初始化时置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;
#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;
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);
}
}
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;
}
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 ;
cout << "Input arcs(v1, v2 & w):" ;
cin >> v1 >> v2 >> w ;
i = LocateVex(G, v1);
j = LocateVex(G, v2);
j = LocateVex(G, v2);
p = (ArcNode*)malloc(sizeof(ArcNode));
p->adjvex = j;
p->nextarc = G.vexs[i].firstarc;
p->weight = w;
p->adjvex = j;
p->nextarc = G.vexs[i].firstarc;
p->weight = w;
G.vexs[i].firstarc = p;
++G.vexs[j].indegree; //每次都增加一个入度
}
++G.vexs[j].indegree; //每次都增加一个入度
}
}
//-------------top logical sort---------------------
//拓扑排序函数
bool TopLogicalSort(ALGraph G) {
ArcNode *p;
int i,k;
int top = -1;
//虚拟栈顶
int count = 0; //用来计有多少个顶点访问到了
int count = 0; //用来计有多少个顶点访问到了
for (i=0; i<G.vexnum; i++) {
//把入度为0的顶点入栈
if (G.vexs[i].indegree == 0) {
G.vexs[i].indegree = top;
top = i;
}
}
if (G.vexs[i].indegree == 0) {
G.vexs[i].indegree = top;
top = i;
}
}
while (top+1) {
//栈不为空时执行
i = top;
top = G.vexs[i].indegree;
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;
}
}
}
//对以该顶点为尾的弧的头顶点进行处理
//每个都入度-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;
}
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;
//-----------------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); //入栈
}
}
if (G.vexs[i].indegree==0) {
elem.push(i); //入栈
}
}
while (!elem.empty()) {
i = elem.top(); //弹出栈顶元素
elem.pop();
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--;
k = p->adjvex;
G.vexs[k].indegree--;
if (G.vexs[k].indegree==0) {
elem.push(k);
}
}
}
elem.push(k);
}
}
}
cout << endl;
if (count<G.vexnum) return false;
else return true;
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;
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;
int main() {
ALGraph G;
cout << "You must input a directed graph!" << endl;
CreatALGraph(G);
CreatALGraph(G);
LogicalJudge(G);
system("pause");
return 0;
}
return 0;
}