邻接表实现图论的各个算法

来源:互联网 发布:百度云管家mac版 编辑:程序博客网 时间:2024/06/06 12:48

/*在这个代码里面,我主要实现的利用邻接表来存储图论,定义了一个类,里面有一个私有的node **a;这个表示的是一维的指针数组,但是在邻接矩阵实现里面也有一个int *aa,这个是动态生成二维数组,注意两者的类的构造函数和析构函数的区别,是个重点!

主要实现算法:深度宽度遍历,拓扑排序,单源最短路径dijkstra,最小生成树(prim)等等

#include<iostream>#include<queue>using namespace std;const int INF = 123123123;enum resultcode{success,failure,notpresent,overflow,duplicate};struct node{int adjvex;node *next;int w;node(){next = NULL;}node(int adj, int ww, node *ne){next = ne;w = ww;adjvex = adj;}};class graph{private:int n, e;node** a;void dfs(int v, bool *visited);void bfs(int v, bool *visited);void countindegree(int *indegree);public:graph(int size);~graph();resultcode insert(int u, int v, int w);resultcode remove(int u, int v);bool exist(int u, int v);void bfs();void dfs();void toposort(int *order);bool toposort1(int *order);int prim(int k, int *nearest, int *lowcost);//void floyd(int **d, int **path);floyd是采用邻接矩阵的方法实现,这个难实现void dijsktra(int k, int *d, int *path);//书上dijskstra是采用邻接矩阵来实现的};graph::graph(int size){n = size;e = 0;a = new node*[n];for (int i = 0; i < n; i++){a[i] = NULL;}}graph::~graph(){node *p,*q;for (int i = 0; i < n; i++){p = a[i];q = p;while (p){p = p->next;delete q;q = p;}}delete[]a;}bool graph::exist(int u, int v){if (u<0 || v<0 || u>n - 1 || v>n - 1 || u == v)return false;node *p = a[u];while (p&&p->adjvex != v)p = p->next;if (!p)return false;elsereturn true;}resultcode graph::insert(int u, int v, int w){if (u<0 || v<0 || u>n - 1 || v>n - 1 || u == v)return failure;if (exist(u, v))return duplicate;node *p = new node(v, w, a[u]);//头插法a[u] = p;e++;return success;}resultcode graph::remove(int u, int v){if (u<0 || v<0 || u>n - 1 || v>n - 1 || u == v)return failure;node *p = a[u];node *q = NULL;while (p&&p->adjvex != v){q = p;p = p->next;}if (p == NULL)return notpresent;if (q)//非表头{q->next = p->next;}elsea[u] = a[u]->next;delete p;e--;return success;}void graph::dfs(int v, bool *visited){visited[v] = true;cout << v << " ";for (node *p = a[v]; p; p = p->next){if (!visited[p->adjvex])dfs(p->adjvex, visited);}}void graph::dfs(){bool *visited = new bool[n];for (int i = 0; i < n; i++){visited[i] = false;}for (int i = 0; i < n; i++){if (!visited[i])dfs(i, visited);}delete[]visited;}void graph::bfs(int v, bool *visited){visited[v] = true;cout << v << " ";queue<int> q;q.push(v);while (!q.empty()){int t = q.front();q.pop();for (node *p = a[t]; p; p = p->next){if (!visited[p->adjvex]){visited[p->adjvex] = true;cout << p->adjvex << " ";q.push(p->adjvex);}}}}void graph::bfs(){bool *visited = new bool[n];for (int i = 0; i < n; i++){visited[i] = false;}for (int i = 0; i < n; i++){if (!visited[i])bfs(i, visited);}delete []visited;}void graph::countindegree(int *indegree){for (int i = 0; i < n; i++){for (node *p = a[i]; p; p = p->next){indegree[p->adjvex]++;}}}void graph::toposort(int *order){int *indegree = new int[n];for (int i = 0; i < n; i++)indegree[i] = 0;countindegree(indegree);int top = -1;for (int i = 0; i < n; i++){if (indegree[i] == 0){indegree[i] = top;top = i;}}for (int i = 0; i < n; i++){if (top == -1){cout << "存在环路" << endl;return;}int j = top;top = indegree[top];order[i] = j;cout << j << " ";for (node *p = a[j]; p; p = p->next){int k = p->adjvex;indegree[k]--;if (!indegree[k]){indegree[k] = top;top = k;}}}delete[]indegree;}bool graph::toposort1(int *order){int *indegree = new int[n];for (int i = 0; i < n; i++)indegree[i] = 0;countindegree(indegree);queue<int> q;for (int i = 0; i < n; i++){if (indegree[i] == 0)q.push(i);}int cnt = 0;while (!q.empty()){int t = q.front();q.pop();order[cnt++] = t;cout << t << " ";for (node *p = a[t]; p; p = p->next){indegree[p->adjvex]--;if (indegree[p->adjvex] == 0)q.push(p->adjvex);}}delete[]indegree;if (cnt != n)return false;elsereturn true;}int  graph::prim(int k, int *nearest, int *lowcost){int ans = 0;bool *mark = new bool[n];node *p;for (int i = 0; i < n; i++){mark[i] = false;nearest[i] = -1;lowcost[i] = INF;}mark[k] = true;nearest[k] = k;lowcost[k] = 0;for (int i = 1; i < n; i++){for (p = a[k]; p; p = p->next){if (!mark[p->adjvex] && lowcost[p->adjvex]>p->w){lowcost[p->adjvex] = p->w;nearest[p->adjvex] = k;}}int MIN = INF;for (int j = 0; j < n; j++){if (!mark[j] && lowcost[j] < MIN){MIN = lowcost[j];k = j;}}ans += MIN;mark[k] = true;}delete[]mark;return ans;}void graph::dijsktra(int k, int *d, int *path){bool *mark = new bool[n];for (int i = 0; i < n; i++){d[i] = INF;path[i] = -1;}for (int i = 0; i < n; i++){mark[i] = false;node *p = a[k];for (; p; p = p->next){int j = p->adjvex;d[j] = p->w;path[j] = k;}}mark[k] = true;d[k] = 0;for (int i = 1; i < n; i++){node *p = a[k];for (; p; p = p->next){if (mark[p->adjvex] == false && d[p->adjvex]>d[k] + p->w){d[p->adjvex] = d[k] + p->w;path[p->adjvex] = k;}}int MIN = INF;for (int j = 0; j < n; j++){if (mark[j] == false && d[j] < MIN){MIN = d[j];k = j;}}mark[k] = true;}delete[]mark;}int main(){/*graph g(6);g.insert(0, 1, 6);//检查插入g.insert(0, 2, 1);//检查插入g.insert(0, 3, 5);g.insert(1, 0, 6);g.insert(1, 4, 3);g.insert(1, 2, 5);g.insert(2, 1, 5);g.insert(2, 3, 5);g.insert(2, 0, 1);g.insert(2, 4, 6);g.insert(2, 5, 4);g.insert(4, 1, 3);g.insert(4, 2, 6);g.insert(4, 5, 6);g.insert(3, 0, 5);g.insert(3, 2, 5);g.insert(3, 5, 2);g.insert(5, 4, 6);g.insert(5, 2, 4);g.insert(5, 3, 2);int *near = new int[6];int *low = new int[6];cout << g.prim(0, near, low) << endl;delete[]near;delete[]low;*//*graph g(7);g.insert(0, 1, 1);//检查插入g.insert(3, 0, 4);g.insert(1, 3, 2);g.insert(1, 2, 9);g.insert(3, 2, 5);g.insert(4, 1, 3);g.insert(5, 4, 8);g.insert(5, 3, 3);g.insert(6, 5, 3);g.insert(6, 4, 6);*//*graph g(9);g.insert(0, 7, 1);//检查插入g.insert(0, 2, 1);g.insert(1,4,3);g.insert(1, 3, 2);g.insert(1, 2, 9);g.insert(2, 3, 4);g.insert(3, 6, 5);g.insert(3, 5, 8);g.insert(4, 5, 3);g.insert(7, 8, 3);g.insert(8, 6, 3);*//*if (g.del(1, 4)){cout << "成功删除" << endl;}else{cout << "删除失败" << endl;}//检查删除if (g.del(2, 0)){cout << "成功删除" << endl;}else{cout << "删除失败" << endl;}*//*if (g.exist(6, 5))cout << "存在" << endl;elsecout << "不存在" << endl;if (g.exist(2, 0))cout << "存在" << endl;elsecout << "不存在" << endl;*//*cout << "接下来是宽度遍历" << endl;g.bfs();cout << endl;cout << "接下来是深度遍历" << endl;g.dfs();cout << endl;//拓扑序列int *order = new int[9];cout << "拓扑序列" << endl;g.toposort(order);cout << endl;delete []order;*/graph g(6);g.insert(0, 1, 50);//检查插入g.insert(0, 2, 10);//检查插入g.insert(0, 4, 70);g.insert(1, 4, 10);g.insert(1, 2, 15);g.insert(2, 3, 15);g.insert(2, 0, 20);g.insert(4, 3, 30);g.insert(3, 1, 20);g.insert(3, 4, 35);g.insert(5, 3, 3);int *d = new int[6];int *path = new int[6];g.dijsktra(0, d, path);for (int i = 0; i < 6; i++){cout << d[i] << endl;}system("pause");return 0;}

*/