圖處理算法-Kosaraju's-算法
阿新 • • 發佈:2018-05-06
com nbsp class 數據 segment rst 非遞歸實現 非遞歸 實現
1.寫了算法課關於有向圖的作業。
用c++開辟大數組容易出segment fault,後來改用堆開辟。圖的鄰接表用了鏈表表示。
long int numVertexes = 875714; long int numEdges; VertexNode* adjList = new VertexNode[875714];
2.關於圖的存儲,用了鄰接鏈表存儲(用鏈表比vector數組存儲速度快多了)。
2.1 邊表
/********邊表***********/ class EdgeNode { public: long int adjvex; //邊表數據 EdgeNode *next; //邊表指向的下一個節點 EdgeNode(long int adj, EdgeNode *n = NULL): adjvex(adj), next(n){} };
2.2 頂點表
/*********頂點表**********/ class VertexNode { public: long int data; //當前頂點數據 EdgeNode *firstEdge; //頂點第一條邊 // VertexNode(long int d, EdgeNode *fir = NULL) : data(d), firstedge(fir) {} };
2.3 初始化圖邊時用了頭插法
/*************頭插法*************************/ void addEdge(long int a, long int b) { EdgeNode *enode = new EdgeNode(b,NULL); enode->next = (adjList+a)->firstEdge; (adjList+a)->firstEdge = enode; }
3.深度優先搜索
3.1 遞歸實現
偽代碼如下:
輸入:有向圖G和某個頂點i
1.將該頂點i標記為已訪問。
2.對邊(i,j),即頂點i的鄰接點j遍歷:
3.if 存在某個頂點j未被訪問,則對頂點j進行訪問:
DFS(G,j)
c++代碼如下:
/*---------------------第一次dfs-------------------*/ void DFS(Graph graph, long int i) { marked[i] = true; list<long int>::iterator iter; for(iter = graph._storage[i].begin(); iter != graph._storage[i].end(); iter++) { long int temp = *iter; if(!marked[temp]) { DFS(graph, temp); } } time++; ff[time-1] = i; }
/*---------------第二次dfs---------------*/ void DFS2(Graph graph, long int i) { marked[i] = true; leader[i] = s; list<long int>::iterator iter; for(iter = graph._storage[i].begin(); iter != graph._storage[i].end(); iter++) { long int temp = *iter; if(!marked[temp]) { DFS2(graph, temp); } } }
3.2 非遞歸實現
偽代碼如下:
1. 棧初始化,將頂點i入棧。
2. while(棧非空)
x = 棧頂元素
3. 對於每條邊(x,j)進行遍歷:
if 存在某個頂點j未被訪問:
將j標記為已訪問
將j入棧
break;
else:
x出棧
c++代碼:
/*================第一次dfs================*/ void dfsLoop1(Graph graph) { markedInit(); time = 0; for(long int i = length-1; i >= 0; i--) { if(!marked[i]) { DFS1(graph, i); } } } void DFS1(Graph graph, long int i) { stack< VertexNode* > stack; stack.push(graph.adjList+i); marked[i] = true; while(!stack.empty()) { VertexNode *temp = new VertexNode; temp = stack.top(); EdgeNode *p = new EdgeNode(0, NULL); p = temp->firstEdge; int flag = 0; while(p) { if(!marked[p->adjvex]) { marked[p->adjvex] = true; stack.push(graph.adjList + (p->adjvex)); flag = 1; break; } p = p->next; } if(!flag) { ff[time] = temp->data; time++; stack.pop(); } } }
/*================第二次dfs================*/ void dfsLoop2(Graph graph) { markedInit(); time = 0; for(long int i = length-1; i >=0 ; i--) { if(!marked[ff[i]]) { s = ff[i]; DFS2(graph, ff[i]); } } } void DFS2(Graph graph, long int i) { stack < VertexNode* > stack; stack.push(graph.adjList+i); leader[i] = s; marked[i] = true; while(!stack.empty()) { VertexNode *temp = new VertexNode; temp = stack.top(); marked[temp->data] = true; EdgeNode *p = new EdgeNode(0,NULL); p = temp->firstEdge; int flag = 0; while(p) { if(!marked[p->adjvex]) { marked[p->adjvex] = true; stack.push(graph.adjList + p->adjvex); flag = 1; break; } p = p->next; } if(!flag) { leader[temp->data] = s; stack.pop(); } } }
完整代碼:
https://github.com/Shinered/Kosaraju/blob/master/dfs3.cpp
圖處理算法-Kosaraju's-算法