1. 程式人生 > >數據結構與算法基礎 模塊五

數據結構與算法基礎 模塊五

end number 通過 uil names fir clas 前驅 pan

嗯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);
};

數據結構與算法基礎 模塊五