数据结构之图_Graph_List
来源:互联网 发布:java定义二维数组 编辑:程序博客网 时间:2024/06/07 16:32
#ifndef GRAPH_LIST_H_INCLUDED
#define GRAPH_LIST_H_INCLUDED
#include<iostream>
#include<queue>
#include<stack>
using std::cout;
using std::cin;
using std::endl;
#define GRAPH_LIST_H_INCLUDED
#include<iostream>
#include<queue>
#include<stack>
using std::cout;
using std::cin;
using std::endl;
struct Edge
{
friend class Graph_List;
Edge(int ver, int w, Edge* e = NULL){ VerAdj = ver; cost = w; link = e; }
int VerAdj;/*链接顶点序列,从0开始编号*/
int cost;/*边的权值*/
Edge* link;/*指向下一个节点的指针*/
{
friend class Graph_List;
Edge(int ver, int w, Edge* e = NULL){ VerAdj = ver; cost = w; link = e; }
int VerAdj;/*链接顶点序列,从0开始编号*/
int cost;/*边的权值*/
Edge* link;/*指向下一个节点的指针*/
};
struct Vertex
{
friend class Graph_List;
int VerName;/*顶点的头指针*/
Edge* adjacent;/*边链表的头指针*/
};
{
friend class Graph_List;
int VerName;/*顶点的头指针*/
Edge* adjacent;/*边链表的头指针*/
};
class Graph_List
{
private:
Vertex *Head;/*顶点链表的头指针*/
int graphsize;/*图中当前顶点的个数*/
int MaxGraphSize;
public:
Graph_List(int MaxSize = 100) :MaxGraphSize(MaxSize),Head(NULL){};
~Graph_List();
void CreatGraph();/*图的构建*/
int GetWeight(const int& v1, const int& v2);/*返回权值*/
void InsertEdge(const int& v1, const int& v2);/*插入边*/
void DeleEdge(const int& v1, const int& v2);/*删除边*/
int GetFirstNeighbor(const int &v);/*顶点v的第一个链接顶点*/
int GetNextNeighbor(const int& v1, const int& v2);/*顶点v的下一个个链接顶点*/
void REDF(const int& v, int* visited);/*深度遍历的递归实现*/
void DepthFirstSearch();/*深度遍历*/
void BFS(const int& s);/*广度遍历*/
void Show();/*测试函数,show图的边及顶点*/
void DShortestPath(const int& v);/*Djkstra算法*/
};
void Graph_List::CreatGraph()
{
int e;
int from, to, weight;
Head = new Vertex[MaxGraphSize];
cout << "请输入顶点个数:";
cin >> graphsize;
for (int i = 0; i<graphsize; i++)
{
Head[i].VerName = i;
Head[i].adjacent = NULL;
}
cout << "请输入边的条数:";
cin >> e;
for (int i = 0; i<e; i++)
{
cout << "请输入新边的始点,终点,和权值:";
cin >> from >> to >> weight;
Edge* p = new Edge(to, weight);
Edge* q = Head[from].adjacent;
if (q == NULL)
{
Head[from].adjacent = p;
}
else
{
while (q->link != NULL)
{
q = q->link;
}
q->link = p;
{
int e;
int from, to, weight;
Head = new Vertex[MaxGraphSize];
cout << "请输入顶点个数:";
cin >> graphsize;
for (int i = 0; i<graphsize; i++)
{
Head[i].VerName = i;
Head[i].adjacent = NULL;
}
cout << "请输入边的条数:";
cin >> e;
for (int i = 0; i<e; i++)
{
cout << "请输入新边的始点,终点,和权值:";
cin >> from >> to >> weight;
Edge* p = new Edge(to, weight);
Edge* q = Head[from].adjacent;
if (q == NULL)
{
Head[from].adjacent = p;
}
else
{
while (q->link != NULL)
{
q = q->link;
}
q->link = p;
}
}
}
}
void Graph_List::Show()
{
cout << "show:" << endl;
for (int i = 0; i<graphsize; i++)
{
cout << Head[i].VerName;
Edge* p = Head[i].adjacent;
while (p)
{
cout << p->VerAdj;
p = p->link;
}
cout << endl;
}
}
{
cout << "show:" << endl;
for (int i = 0; i<graphsize; i++)
{
cout << Head[i].VerName;
Edge* p = Head[i].adjacent;
while (p)
{
cout << p->VerAdj;
p = p->link;
}
cout << endl;
}
}
Graph_List::~Graph_List()
{
for (int i = 0; i<graphsize; i++)/*删除每个顶点的边链表*/
{
Edge* p = Head[i].adjacent;
while (p != NULL)
{
Head[i].adjacent = p->link;
delete p;/*每一次删除的都是第二个*/
p = Head[i].adjacent;
}
}
delete[] Head;
}
{
for (int i = 0; i<graphsize; i++)/*删除每个顶点的边链表*/
{
Edge* p = Head[i].adjacent;
while (p != NULL)
{
Head[i].adjacent = p->link;
delete p;/*每一次删除的都是第二个*/
p = Head[i].adjacent;
}
}
delete[] Head;
}
int Graph_List::GetWeight(const int& v1, const int& v2)
{
if (v1<0 || v2<0)
{
return 0;
}
{
if (v1<0 || v2<0)
{
return 0;
}
Edge *p = Head[v1].adjacent;
while (p != NULL)
{
if (p->VerAdj == v2)
{
return p->cost;
}
p = p->link;
}
while (p != NULL)
{
if (p->VerAdj == v2)
{
return p->cost;
}
p = p->link;
}
return 0;
}
}
void Graph_List::InsertEdge(const int& v1, const int& v2)
{
if (v1<0 || v2<0)
{
cout << "图中无此顶点,不能插入边.";
return;
}
Edge* p = Head[v1].adjacent;
{
if (v1<0 || v2<0)
{
cout << "图中无此顶点,不能插入边.";
return;
}
Edge* p = Head[v1].adjacent;
while (p->link != NULL)
{
if (p->VerAdj == v2)
{
cout << "次边已存在.";
return;
}
p = p->link;
}
{
if (p->VerAdj == v2)
{
cout << "次边已存在.";
return;
}
p = p->link;
}
cout << "请输入边<" << v1 << "," << v2 << ">的权值:";
int weight;
cin >> weight;
p->link = new Edge(v2, weight);
cout << "成功插入边<" << v1 << "," << v2 << ">." << endl;
}
int weight;
cin >> weight;
p->link = new Edge(v2, weight);
cout << "成功插入边<" << v1 << "," << v2 << ">." << endl;
}
void Graph_List::DeleEdge(const int& v1, const int& v2)
{
if (v1<0 || v2<0)
{
std::cout << "顶点不在此图中.";
return;
}
{
if (v1<0 || v2<0)
{
std::cout << "顶点不在此图中.";
return;
}
Edge* p = Head[v1].adjacent;
while (p != NULL)
{
if (p == Head[v1].adjacent && (p->VerAdj == v2))
{ /*第一条边为目标边*/
// std::cout<<"此边已存在.";
Head[v1].adjacent = p->link;
delete p;
std::cout << "<" << v1 << "," << v2 << ">已经删除." << std::endl;
while (p != NULL)
{
if (p == Head[v1].adjacent && (p->VerAdj == v2))
{ /*第一条边为目标边*/
// std::cout<<"此边已存在.";
Head[v1].adjacent = p->link;
delete p;
std::cout << "<" << v1 << "," << v2 << ">已经删除." << std::endl;
}
else if (p->link != NULL && (p->link->VerAdj == v2))
{
/*中间的一条边为目标边*/
else if (p->link != NULL && (p->link->VerAdj == v2))
{
/*中间的一条边为目标边*/
// std::cout<<"此边已存在.";
Edge *temp = p->link;
p->link = temp->link;
delete temp;
std::cout << "<" << v1 << "," << v2 << ">已经删除." << std::endl;
Edge *temp = p->link;
p->link = temp->link;
delete temp;
std::cout << "<" << v1 << "," << v2 << ">已经删除." << std::endl;
}
else if (p->VerAdj == v2)
{/*目标边边为最后一条边*/
std::cout << "此边已存在.";
Edge *temp = p->link;
p->link = temp->link;
delete temp;
std::cout << "<" << v1 << "," << v2 << ">已经删除." << std::endl;
}
p = p->link;
}
}
else if (p->VerAdj == v2)
{/*目标边边为最后一条边*/
std::cout << "此边已存在.";
Edge *temp = p->link;
p->link = temp->link;
delete temp;
std::cout << "<" << v1 << "," << v2 << ">已经删除." << std::endl;
}
p = p->link;
}
}
int Graph_List::GetFirstNeighbor(const int &v)
{
if (v<0)
{
std::cout << "顶点不在此图中.";
return -1;
}
{
if (v<0)
{
std::cout << "顶点不在此图中.";
return -1;
}
Edge* p = Head[v].adjacent;
if (p != NULL)
{
return p->VerAdj;
}
return -1;
}
if (p != NULL)
{
return p->VerAdj;
}
return -1;
}
int Graph_List::GetNextNeighbor(const int& v1, const int& v2)
{
if (v1<0 || v2<0)
{
std::cout << "顶点不在此图中.";
return -1;
}
Edge *p = Head[v1].adjacent;
while (p->VerAdj != v2&&p != NULL)
p = p->link;
if (p == NULL)
return -1;
p = p->link;
if (p == NULL)
{
return -1;
}
return p->VerAdj;
}
{
if (v1<0 || v2<0)
{
std::cout << "顶点不在此图中.";
return -1;
}
Edge *p = Head[v1].adjacent;
while (p->VerAdj != v2&&p != NULL)
p = p->link;
if (p == NULL)
return -1;
p = p->link;
if (p == NULL)
{
return -1;
}
return p->VerAdj;
}
void Graph_List::DepthFirstSearch()
{
int *visited = new int[graphsize];
for (int k = 0; k<graphsize; k++)
visited[k] = 0;
REDF(0, visited);
delete[] visited;
}
{
int *visited = new int[graphsize];
for (int k = 0; k<graphsize; k++)
visited[k] = 0;
REDF(0, visited);
delete[] visited;
}
void Graph_List::REDF(const int& v, int* visited)
{
std::cout << v << " ";
visited[v] = 1;/*设置成为被访问*/
int w = GetFirstNeighbor(v);
while (w != -1)
{
if (!visited[w])
{
REDF(w, visited);
}
w = GetNextNeighbor(v, w);/*回溯,w为v的上一个顶点*/
}
{
std::cout << v << " ";
visited[v] = 1;/*设置成为被访问*/
int w = GetFirstNeighbor(v);
while (w != -1)
{
if (!visited[w])
{
REDF(w, visited);
}
w = GetNextNeighbor(v, w);/*回溯,w为v的上一个顶点*/
}
}
void Graph_List::BFS(const int& s)
{
int* visited = new int[graphsize];
for (int k = 0; k<graphsize; k++)
visited[k] = 0;
std::cout << s << " ";
visited[s] = 1;
std::queue<int> graphQueue;
graphQueue.push(s);
while (!graphQueue.empty())
{
int v = graphQueue.front();
graphQueue.pop();
int w = GetFirstNeighbor(v);
while (w != -1)
{
if (!visited[w])
{
std::cout << w << " ";
visited[w] = 1;
graphQueue.push(w);
}
w = GetNextNeighbor(v, w);
}
}
delete[] visited;
{
int* visited = new int[graphsize];
for (int k = 0; k<graphsize; k++)
visited[k] = 0;
std::cout << s << " ";
visited[s] = 1;
std::queue<int> graphQueue;
graphQueue.push(s);
while (!graphQueue.empty())
{
int v = graphQueue.front();
graphQueue.pop();
int w = GetFirstNeighbor(v);
while (w != -1)
{
if (!visited[w])
{
std::cout << w << " ";
visited[w] = 1;
graphQueue.push(w);
}
w = GetNextNeighbor(v, w);
}
}
delete[] visited;
}
void Graph_List::DShortestPath(const int& v)
{
/*
path[]记录v到i的最短路径上的顶点的i的前驱节点
dist[]记录从v到i的最短路径
辅助数组s[],数组的初值设为0,一旦顶点i访问,s[i]设置为1
(1)设s为初始顶点,Ds=0
(2)在为范文的顶点中选择Dv的最小顶点,访问v,另s[v]=1
(3)一次考察v的连接顶点w,若Dv+weight(<v,w>)<Dv,则更新Dw的值,使Dw=Dv+weight(<v,w>)
(4)重复2,3,直到所有的顶点都被访问完
*/
{
/*
path[]记录v到i的最短路径上的顶点的i的前驱节点
dist[]记录从v到i的最短路径
辅助数组s[],数组的初值设为0,一旦顶点i访问,s[i]设置为1
(1)设s为初始顶点,Ds=0
(2)在为范文的顶点中选择Dv的最小顶点,访问v,另s[v]=1
(3)一次考察v的连接顶点w,若Dv+weight(<v,w>)<Dv,则更新Dw的值,使Dw=Dv+weight(<v,w>)
(4)重复2,3,直到所有的顶点都被访问完
*/
//int v;
int k, u;
Edge*p;
int max = 10000;
int n = graphsize;
int* path = new int[graphsize];
int* dist = new int[graphsize];
int* s = new int[graphsize];/*s数组记录是否被访问过*/
for (int i = 0; i<n; i++)/*初始化数组*/
{
path[i] = -1;
dist[i] = max;
s[i] = 0;
}
dist[v] = 0; s[v] = 1;/*起始顶点标记为被访问*/
p = Head[v].adjacent;
u = v;/*u为即将被访问的顶点*/
for (int j = 0; j<n; j++)
{
while (p != NULL)
{
/*修改u连接的顶点s[],path[],dist[]的值*/
k = p->VerAdj;
if (s[k] != 1 && dist[u] + p->cost<dist[k])
{
dist[k] = dist[u] + p->cost;
path[k] = u;
}
p = p->link;
}
}
int k, u;
Edge*p;
int max = 10000;
int n = graphsize;
int* path = new int[graphsize];
int* dist = new int[graphsize];
int* s = new int[graphsize];/*s数组记录是否被访问过*/
for (int i = 0; i<n; i++)/*初始化数组*/
{
path[i] = -1;
dist[i] = max;
s[i] = 0;
}
dist[v] = 0; s[v] = 1;/*起始顶点标记为被访问*/
p = Head[v].adjacent;
u = v;/*u为即将被访问的顶点*/
for (int j = 0; j<n; j++)
{
while (p != NULL)
{
/*修改u连接的顶点s[],path[],dist[]的值*/
k = p->VerAdj;
if (s[k] != 1 && dist[u] + p->cost<dist[k])
{
dist[k] = dist[u] + p->cost;
path[k] = u;
}
p = p->link;
}
}
int ldist = max;
for (int i = 0; i<n; i++)
{
/*确定即将被访问的顶点u*/
if (dist[i]>0 && dist[i]<ldist&&s[i] == 0)
{
ldist = dist[i];
u = i;
}
}
s[u] = 1;/*访问u*/
p = Head[u].adjacent;
for (int i = 0; i<n; i++)
std::cout << path[i] << " ";
for (int i = 0; i<n; i++)
std::cout << dist[i] << " ";
delete[] path;
delete[] dist;
}
for (int i = 0; i<n; i++)
{
/*确定即将被访问的顶点u*/
if (dist[i]>0 && dist[i]<ldist&&s[i] == 0)
{
ldist = dist[i];
u = i;
}
}
s[u] = 1;/*访问u*/
p = Head[u].adjacent;
for (int i = 0; i<n; i++)
std::cout << path[i] << " ";
for (int i = 0; i<n; i++)
std::cout << dist[i] << " ";
delete[] path;
delete[] dist;
}
#endif
0 0
- 数据结构之图_Graph_List
- 数据结构之图
- 数据结构复习之【图】
- 数据结构之图
- 基础数据结构之图
- 数据结构之图-邻接矩阵
- 数据结构之图详解
- C++数据结构之图
- Python数据结构之图
- 数据结构之图
- 数据结构之图
- 数据结构算法之图
- 数据结构之图
- 数据结构之--图
- 数据结构之---图(一)
- 数据结构复习之【图】
- 数据结构之图
- 数据结构之--图
- Kibana User Guide [4.2] » Using Kibana in a Production Environment
- Android中的DrawRect()参数解析
- 自定义数据排序(Comparable,Comparator)JAVA126
- Struts2的简单入门
- IO读写注意处理数据只写了一部分的情况
- 数据结构之图_Graph_List
- linux设备驱动归纳总结(十):1.udev&misc 2
- xmanager - xstart - The X11 forwarding request was rejected
- 在Sublime Text 3中配置编译和运行Java程序
- ueditor过滤
- Dijkstra算法
- JavaCore/HeapDump文件分析工具
- appStore检查更新的json地址http://itunes.apple.com/lookup?id=%@&country=cn
- 【jQuery】stop( ) 停止动画