/*在这个代码里面,我主要实现的利用邻接表来存储图论,定义了一个类,里面有一个私有的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;
else
return 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;
}
else
a[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;
else
return 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;
else
cout << "不存在" << endl;
if (g.exist(2, 0))
cout << "存在" << endl;
else
cout << "不存在" << 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;
}
*/