標籤:建議 cout 死迴圈 pre -- creat 資料結構與演算法 pop ++
嗯mm 現在到演算法階段了,比較多的代碼,建議有時間自己在電腦上敲一下,加深理解。
那麼,現在以問題來帶入:
1、什麼是拓樸排序?
對一個有向非循環圖進行拓撲排序,是將G中所有頂點排成一個線性序列,使得圖中任意一對頂點u和v,若邊(u,v)∈E(G),則u線上性序列中出現在v之前。
一個網應該是一個有向非循環圖,即不應該帶有迴路,因為若帶有迴路,則迴路上的所有活動都無法進行(對於資料流來說就是死迴圈)。在AOV網中,若不存在迴路,則所有活動可排列成一個線性序列,使得每個活動的所有前驅活動都排在該活動的前面,我們把此序列叫做拓撲序列,由AOV網構造拓撲序列的過程叫做拓撲排序(Topological sort)。
註:AOV網的拓撲序列不是唯一的,滿足上述定義的任一線性序列都稱作它的拓撲序列。
2、拓樸排序的實現步驟
①在有向圖中選一個沒有前驅的頂點並且輸出
②刪除該頂點和所有以它為尾的弧(白話就是:刪除所有和它有關的邊)
③重複上述兩步,直至所有頂點輸出,或者當前圖中不存在無前驅的頂點為止,後者代表我們的有向圖是有環的,因此,也可以通過拓撲排序來判斷一個圖是否有環。
3、拓樸排序的代碼實現:
for (i = 0; i != this->vexnum; i++) {
temp = this->arc[i].firstarc;
while (temp) {
++this->indegree[temp->adjvex];
temp = temp->next;
}
}
for (i = 0; i != this->vexnum; i++) {
if (!indegree[i]) {
s.push(i);
}
}
//count用於計算輸出的頂點個數
int count=0;
while (!s.empty()) {//如果棧為空白,則結束迴圈
i = s.top();
s.pop();
cout << this->arc[i].data<<" ";
temp = this->arc[i].firstarc;
while (temp) {
if (!(--this->indegree[temp->adjvex])) {
s.push(temp->adjvex);
}
temp = temp->next;
}
++count;
}
if (count == this->vexnum) {
cout << endl;
return true;
}
return false;
}
鄰接表格儲存體的代碼實現:
#include<iostream>
#include<string>
#include<stack>
using namespace std;
struct ArcNode {
ArcNode * next;
int adjvex;
};
struct Vnode {
string data;
ArcNode * firstarc;
};
class Graph_DG {
private:
int vexnum; //圖的頂點數
int edge; //圖的邊數
int * indegree; //每條邊的入度情況
Vnode * arc; //鄰接表
public:
Graph_DG(int, int);
~Graph_DG();
bool check_edge_value(int,int);
void createGraph();
void print();
bool topological_sort();
bool topological_sort_by_dfs(); void dfs(int n,bool * & visit, stack<string> & result);
};
資料結構與演算法基礎 模組五