这里用邻接表和一个入度数组实现
topo时候保持一个栈 把入度为0的点压入栈中
每次将栈中元素出栈 同时减去这个点邻接点的入度
如果临界点的入度为0 则入栈
栈的循环直到栈为空
然后检查是否有环 扫面入度数组 如果有不为0的元素 则存在环
解释可能有不清楚的地方 以后有时间重新写过 睡觉去了!
#include <iostream>
#include <stack>
#include <hash_set>
#define N 26
struct node
{
int adjVex;
node* next;
}adj[N];
int inDegree[N];
std::hash_set<int> map;
void init()
{
memset(inDegree, 0, sizeof(inDegree));
for(int i = 0; i < N; i++)
{
adj[i].adjVex = i;
adj[i].next = NULL;
}
};
void create(int u, int v)
{
if(map.find(u) == map.end())
map.insert(u);
if(map.find(v) == map.end())
map.insert(v);
node* n = new node();
n->adjVex = v;
n->next = adj[u].next;
adj[u].next = n;
inDegree[v]++;
};
void printAdjList()
{
std::cout << "Adj list:\n";
for(int i = 0; i < N; i++)
{
char curElem = adj[i].adjVex + 'A';
node* n = adj[i].next;
bool printBreak = false;
if(n)
{
printBreak = true;
std::cout << curElem << " ";
}
while(n)
{
char cur = n->adjVex + 'A';
std::cout << cur << " ";
n = n->next;
}
if(printBreak)
std::cout << "\n";
}
};
bool topo()
{
std::stack<int> st;
//int cnt = 0;
for(int i = 0; i < N; i++)
{
if(inDegree[i] == 0 && map.find(i) != map.end())
st.push(i);
}
int top;
std::cout << "Topo result:\n";
while(!st.empty())
{
top = st.top();
st.pop();
char cur = top + 'A';
std::cout << cur << " ";
//cnt++;
node* n = adj[top].next;
while(n)
{
int k = n->adjVex;
inDegree[k]--;
if(inDegree[k] == 0)
st.push(k);
n = n->next;
}
}
std::cout << "\n";
for(int i = 0; i < N; i++)
{
if(inDegree[i] != 0)
return false;
}
return true;
};
int main()
{
int total;
std::cout << "Put the total of the pairs: ";
std::cin >> total;
init();
char u, v;
std::cout << "-u- -v-\n";
while(total--)
{
std::cin >> u >> v;
create(u - 'A', v - 'A');
}
printAdjList();
int canTopo = topo();
if(!canTopo)
std::cout << "This graph could not be topoed!\n";
return 0;
}