// 2.1 邻接表+顺序栈 实现有向无环图的拓扑排序
#include<iostream>
using namespace std;
#define OK 1
#define ERROR 0
#define OVERFLOW -1
#define MAXSIZE 100 //顺序栈存储空间的初始分配量
#define MAX_NODES 5 // 图的节点数
typedef int Status;
typedef int SElemType;
// 定义栈
typedef struct
{
SElemType *base;
SElemType *top;
int stacksize;
}SqStack;
// 初始化栈
Status InitStack(SqStack &S)
{
S.base = new SElemType[MAXSIZE];
if(!S.base)
exit(OVERFLOW);
S.top=S.base;
S.stacksize=MAXSIZE;
return OK;
}
// 入栈
Status Push(SqStack &S,SElemType e)
{
if(S.top-S.base==S.stacksize)
return ERROR;
*S.top=e;
S.top++;
return OK;
}
// 出栈
Status Pop(SqStack &S,SElemType &e)
{
if(S.top==S.base)
return ERROR;
S.top--;
e=*S.top;
return OK;
}
// 栈的判空
int StackEmpty(SqStack S)
{
if(S.top==S.base)
return 1;
else
return 0;
}
// 定义结点
typedef struct Node
{
int vertex;
struct Node* next;
} Node;
// 定义图
typedef struct Graph
{
Node* adjList[MAX_NODES]; // 指针数组
int numNodes;
} Graph;
// 创建一个新节点
Node* createNode(int v)
{
Node* newNode = (Node*)malloc(sizeof(Node));
newNode->vertex = v;
newNode->next = NULL;
return newNode;
}
// 初始化图
void initGraph(Graph* g, int nodes)
{
g->numNodes = nodes;
for (int i = 0; i < nodes; i++)
{
g->adjList[i] = NULL; // 初始化邻接表
}
}
// 添加边
void addEdge(Graph* g, int u, int v)
{
Node* newNode = createNode(v);
newNode->next = g->adjList[u];
g->adjList[u] = newNode; // 将新节点添加到邻接表的头部,前插法
}
// 统计节点的入度信息
void FindInDegree(Graph* g,int indegree[])
{
int i;
Node* p = (Node*)malloc(sizeof(Node));
for(i=0;i<MAX_NODES;i++)
indegree[i]=0;
for(i=0;i<MAX_NODES;i++)
{
p=g->adjList[i];
while(p!=NULL)
{
indegree[p->vertex]++;
p=p->next;
}
}
}
// 拓扑排序
Status TopologicalSort(Graph* g,int topo[])
{
int indegree[MAX_NODES],i,m,k;
FindInDegree(g,indegree); // indegree[MAX_NODES]数组里存放每个节点的入度信息
SqStack S;
InitStack(S);
for(i=0;i<g->numNodes;i++)
if(!indegree[i])
Push(S,i); // 入度为 0 的节点入栈
m=0;
Node* p = (Node*)malloc(sizeof(Node));
while(!StackEmpty(S))
{
Pop(S,i);
topo[m]=i; // 排序结果保存在 topo[MAX_NODES]数组中
++m;
p=g->adjList[i];
while(p!=NULL)
{
k=p->vertex;
--indegree[k]; // 节点的入度减 1
if(indegree[k]==0)
Push(S,k);
p=p->next; // 入栈节点的邻接节点的入度减 1
}
}
if(m<g->numNodes)
return ERROR;
else return OK;
}
int main() {
Graph g;
int topo[MAX_NODES],i;
initGraph(&g, MAX_NODES);
// 创建有向图的边
addEdge(&g, 0, 2);
addEdge(&g, 1, 2);
addEdge(&g, 2, 3);
addEdge(&g, 2, 4);
addEdge(&g, 3, 4);
if(TopologicalSort(&g,topo))
{
cout<<"拓扑排序为:"<<endl;
for(i=0;i<MAX_NODES;i++)
cout<<topo[i]<<" ";
cout<<endl;
}
else
cout<<"该有向图存在回路,拓扑排序失败"<<endl;
}
实验2.1 实现有向无环图的拓扑排序
于 2024-10-05 17:09:01 首次发布