Adjacency Lists + DFS.
来源:互联网 发布:昆明行知中学图片 编辑:程序博客网 时间:2024/06/05 16:23
// Adjacency Lists + DFS.#ifndef _IOSTREAM_H#include <iostream.h>#include <conio.h>#define _IOSTREAM_H#endifenum Boolean { FALSE, TRUE};template <class Type> class List;template <class Type> class ListIterator;template <class Type>class ListNode {friend class List<Type>;friend class ListIterator<Type>;private: Type data; ListNode *link; ListNode(Type);};template <class Type>ListNode<Type>::ListNode(Type Default){ data = Default; link = 0;}template <class Type>class List {friend class ListIterator<Type>;public: List() {first = 0;}; void Insert(Type); void Delete(Type);private: ListNode<Type> *first;};template <class Type>void List<Type>::Insert(Type k){ListNode<Type> *newnode = new ListNode<Type>(k);newnode->link = first;first = newnode;}template <class Type>void List<Type>::Delete(Type k){ ListNode<Type> *previous = 0; ListNode<Type> *current;for (current = first; current && current->data != k;previous = current, current = current->link); if (current) { if (previous) previous->link = current->link; else first = first->link; delete current; }}template <class Type>class ListIterator{public: ListIterator(const List<Type>& l): list(l) {current = l.first;} Type* First(); Type* Next(); Boolean NotNull(); Boolean NextNotNull();private: const List<Type> &list; ListNode<Type>* current;};template <class Type>Type* ListIterator<Type>::First() { if (current) return ¤t->data; else return 0;}template <class Type>Type* ListIterator<Type>::Next() { current = current->link; return ¤t->data;}template <class Type>Boolean ListIterator<Type>::NotNull(){if (current) return TRUE;else return FALSE;}template <class Type>Boolean ListIterator<Type>::NextNotNull(){if (current->link) return TRUE;else return FALSE;}//template <class Type>ostream& operator<<(ostream& os, List<char>& l){ ListIterator<char> li(l); if (!li.NotNull()) return os; os << *li.First() << endl; while (li.NextNotNull()) os << *li.Next() << endl; return os;}class Graph{private: List<int> *HeadNodes; int n; void DFS(const int); Boolean *visited; int num; int *low; int *dfn; void DfnLow(const int, const int);public: Graph(const int vertices = 0) : n(vertices) { HeadNodes = new List<int>[n];}; void DFS(); void Setup(); void Setup2(); void DfnLow(const int); void Components(); void Out();};void Graph::Setup(){ HeadNodes[0].Insert(2); HeadNodes[0].Insert(1); HeadNodes[1].Insert(4); HeadNodes[1].Insert(3); HeadNodes[1].Insert(0); HeadNodes[2].Insert(6); HeadNodes[2].Insert(5); HeadNodes[2].Insert(0); HeadNodes[3].Insert(7); HeadNodes[3].Insert(1); HeadNodes[4].Insert(7); HeadNodes[4].Insert(1); HeadNodes[5].Insert(7); HeadNodes[5].Insert(2); HeadNodes[6].Insert(7); HeadNodes[6].Insert(2); HeadNodes[7].Insert(6); HeadNodes[7].Insert(5); HeadNodes[7].Insert(4); HeadNodes[7].Insert(3);}void Graph::Setup2(){ HeadNodes[0].Insert(1); // HeadNodes[1].Insert(2); HeadNodes[1].Insert(3); HeadNodes[1].Insert(0);// HeadNodes[2].Insert(1); HeadNodes[2].Insert(4); // HeadNodes[3].Insert(5); HeadNodes[3].Insert(1); HeadNodes[3].Insert(4);// HeadNodes[4].Insert(3); HeadNodes[4].Insert(2); // HeadNodes[5].Insert(7); HeadNodes[5].Insert(6);// HeadNodes[6].Insert(7); HeadNodes[6].Insert(5);// HeadNodes[7].Insert(6); HeadNodes[7].Insert(5); HeadNodes[7].Insert(8); HeadNodes[7].Insert(9); HeadNodes[8].Insert(7); HeadNodes[9].Insert(7);}// Drivervoid Graph::DFS(){ visited = new Boolean[n]; // @visited@ is declared as a @Boolean@/(** data member of @Graph@. for (int i = 0; i < n; i++) visited[i] = FALSE; // initially, no vertices have been visited DFS(0); // start search at vertex 0 delete [] visited;}// Workhorsevoid Graph::DFS(const int v)// visit all previously unvisited vertices that are reachable from vertex @v@{visited[v] = TRUE; cout << v << ", "; ListIterator<int> li(HeadNodes[v]); if (! li.NotNull()) return; int w = *li.First(); while (1) { if (! visited[w]) DFS(w); if (li.NextNotNull()) w = *li.Next(); else return; }}void Graph::Components(){int i; visited = new Boolean[n]; for (i = 0; i < n; i++) visited[i] = FALSE; for (i = 0; i < n; i++) if (! visited[i]) {cout << endl << "New Component :"; DFS(i); // @DFS@ is modified to print a vertex when it is visited} delete [] visited;}void Graph::DfnLow(const int x){ num = 1; dfn = new int[n]; low = new int[n]; for (int i = 0; i < n; i++) { dfn[i] = low[i] = 0;} DfnLow(x, -1); delete [] dfn; delete [] low;}void Graph::DfnLow (const int u, const int v){dfn[u] = low[u] = num++; ListIterator<int> li(HeadNodes[u]); if (! li.NotNull()) return;int w = *li.First(); while (1) {if (dfn[w] == 0) { DfnLow(w, u); if (low[w] < low[u]) low[u] = low[w];}else { if (w != v) { if (dfn[w] < low[u]) low[u] = dfn[w]; }}if (li.NextNotNull()) w = *li.Next();else return; }}void Graph::Out(){for (int i = 0; i < n; i++) { cout << i << ": " << dfn[i] << " " << low[i] << endl;}}void main(){ Graph g(10); g.Setup2();// g.Components(); g.DfnLow(3); g.Out(); getch();}