拓扑排序C++实现
思路
拓扑排序在作者看来本质上是每次寻找入度为0节点的图的遍历,所以在进行拓扑排序的时候我们首先要建立一个图,由于是要进行拓扑排序,所以我们要建立的图一定是一个有向图。然后每次去查找邻接矩阵中入度为0的元素输出,然后把这个元素映射过去的arr矩阵中相应的行元素全部置为0,相当于切断此元素指向其他元素的边。然后不断重复此操作即可。
下面给出实现的代码。
#include<iostream>
#include<queue>
#define MAX 100
int arr[MAX][MAX];
int flag[MAX];//记录是否已经访问过该元素
using namespace std;
int findloc(char a[], char c,int n)//查找字符c在数组中的位置
{
int i;
for (i = 0; i < n; i++)
{
if (a[i] == c)
break;
}
return i;
}
int findinnum(char a[], char c, int n)//统计入度数
{
int loc = findloc(a, c, n);
int cnt = 0;
for (int i = 0; i < n; i++)
{
if (arr[i][loc] == 1)
cnt++;
}
return cnt;
}
void creategraph(char a[], int n,int arc)//创建一个数据结构为邻接矩阵的图
{
cout << "输入每条边相邻的两个节点:(前为起点)" << endl;
char c1, c2;
int loc1, loc2;
for(int i=0;i<n;i++)
for (int j = 0; j < n; j++)
{
arr[i][j] = 0;
}
for (int i = 0; i < arc; i++)
{
cin >> c1 >> c2;
loc1 = findloc(a, c1, n);
loc2 = findloc(a, c2, n);
arr[loc1][loc2] = 1;
}
cout << "当前邻接矩阵为:" << endl;
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
cout << arr[i][j] << " ";
}
cout << endl;
}
}
void topsort(char a[], int n)//拓扑排序
{
cout << endl << "拓扑排序:";
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
if (findinnum(a, a[j], n) == 0 && flag[j]==1)
{
cout << a[j] << " ";
flag[j] = 0;
for (int k = 0; k < n; k++)
{
arr[j][k] = 0;
}
break;
}
}
}
}
int main()
{
int n, arc;
cout << "输入顶点数,边数:";
cin >> n >> arc;
char* a = new char[n];
cout << "输入各个顶点名称:";
for (int i = 0; i < n; i++)
{
flag[i] = 1;
}
for (int i = 0; i < n; i++)
{
cin >> a[i];
}
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
{
arr[i][j] = 1;
}
creategraph(a, n, arc);
topsort(a, n);
return 0;
}