您的位置:首页 > 其它

图的存储以及深度优先和广度优先

2016-01-02 20:51 369 查看
<span style="font-size:18px;">   </span><pre name="code" class="cpp">/*
图的存储与遍历
1.读取文件data中图的信息
2.创建图->临接矩阵
3.输出顶点以及临接矩阵
4.将临接矩阵存储转换为临接表存储
5.输出临接表
6.输出深度优先搜素结果
7.输出广度优先搜索结果
*/

#include<iostream>
#include<string>
#include<sstream>
#include<fstream>
using namespace std;

//定义矩阵存储空间
const int MAX_N = 100;//存储空间最大值
const int INF = 65535;//定义为无穷大

//图的矩阵存储
//顶点信息
class Vertex
{
public:
int number;//定义定点下标
int verxname;//顶点名
};

//邻接矩阵存储图
class MGraph
{
public:
int edages[MAX_N][MAX_N];//边数组
int weight[MAX_N];//权重
int Tvertexs, Tedges;//顶点及边总数
Vertex vert[MAX_N];//顶点信息
};

//临接表存储
class Anode;
//顶点
class Vnode
{
public:
int adjverx;//边终点编号
Anode *firstAnode;//下一顶点
};
//边
class Anode
{
public:
int weight;//权重
int vesname;//顶点名称
Anode *nextAnode;//下一顶点
};

//临接表存储图
class FGraph
{
public:
Vnode adjList[MAX_N];//顶点信息
int Tvertexs, Tedges;//总顶点数、边数
};

class Graph
{
public:
Graph()
{
InitMatrix();//初始化临接矩阵
}

~Graph(){}

//初始化
void InitMatrix()
{
for (int i = 0; i < MAX_N; i++)
{
for (int j = 0; j < MAX_N; j++)
{
mgraph.edages[i][j] = INF;//初始化为无穷大
}
}
}

//初始化遍历数组
void InitVisited()
{
for (int i = 0; i < MAX_N; i++)
{
visited[i] = INF;//初始化为无穷大
}
}

//读取信息
void getInfo(string filename)
{
ifstream readfile;
readfile.open(filename);
getline(readfile, verx);//读取顶点信息
getline(readfile, weight);//读取权重
int i = 0;
while (!readfile.eof())
{
if (getline(readfile, edges[i]).good())//读取边
{
i++;
}
}
Tedges = i;//记录边数
}

//创建图
void CreateGraphMatrix()
{
int edge1, edge2;
mgraph.Tvertexs = verx.length();//顶点数
mgraph.Tedges = Tedges;//边数

//处理顶点
for (int i = 0; i < mgraph.Tvertexs; i++)
{
//转换
sstr.clear();//清空内存
sstr << verx[i];//写入一个顶点
sstr >> mgraph.vert[i].verxname;//获取一个顶点
mgraph.vert[i].number = i;//定义顶点编号
}

//处理边
for (int i = 0; i < mgraph.Tedges; i++)
{
//转换
sstr.clear();//清空内存
sstr << weight[i];//写入权重
sstr >> mgraph.weight[i];//获取权重
sstr.clear();
sstr << edges[i][0];//获取一条边始点
sstr >> edge1;
sstr.clear();
sstr << edges[i][1];//获取一条边终点
sstr >> edge2;
int p1 = location(mgraph, edge1);//获取始点边下标
int p2 = location(mgraph, edge2);//获取终点边下标
mgraph.edages[p1][p2] = mgraph.weight[i];//写入该边权重
}
}

//输出邻接矩阵
void display()
{
cout << "Num & Vertex" << endl;
//输出顶点下标以及顶点
for (int i = 0; i < mgraph.Tvertexs; i++)
{
cout << mgraph.vert[i].number << "\t";//下标
cout << mgraph.vert[i].verxname << endl;//顶点
}

cout << "Matrix" << endl;
for (int i = 0; i < mgraph.Tvertexs; i++)
{
for (int j = 0; j < mgraph.Tvertexs; j++)
{
//非无穷大则输出权值,否则输出无穷大标志
if (mgraph.edages[i][j] != INF)
{
cout << mgraph.edages[i][j] << "\t";
}
else
{
cout << "∞" << "\t";
}
}
cout << endl;
}
}

//矩阵存储转为邻接表
void MatTranToList()
{
Anode *p;
fgraph = (FGraph *)malloc(sizeof(FGraph));

//邻接表组始边初始化为空
for (int i = 0; i < mgraph.Tvertexs; i++)
{
fgraph->adjList[i].firstAnode = NULL;
}

//头插法插入顶点以及权重信息
for (int i = 0; i < mgraph.Tvertexs; i++)
{
for (int j = mgraph.Tvertexs - 1; j >= 0; j--)//倒序
{
//头插法
if (mgraph.edages[i][j] != INF)
{
p = (Anode *)malloc(sizeof(Anode));
p->weight = mgraph.edages[i][j];//权重
p->vesname = mgraph.vert[j].verxname;//顶点名称
p->nextAnode = fgraph->adjList[i].firstAnode;//链接后节点
fgraph->adjList[i].firstAnode = p;//链接当前节点
}
}
}
fgraph->Tvertexs = mgraph.Tvertexs;//总顶点数
fgraph->Tedges = mgraph.Tedges;//总边数
}

//输出邻接表
void disp()
{
cout << "List" << endl;
cout << "vertex & weight" << endl;
Anode *p;

//输出顶点名称以及权重
for (int i = 0; i < fgraph->Tvertexs; i++)
{
p = fgraph->adjList[i].firstAnode;//指向首节点
while (p != NULL)//p不为空时循环输出下一节点
{
cout << p->vesname << "&" << p->weight << ends;
p = p->nextAnode;
}
cout << endl;
}
}

//广度优先
void BfsOut()
{
cout << "BFS" << endl;
InitVisited();//初始化遍历数组
BFS(fgraph, 0);//广度优先输出,从0开始
cout << endl;
}

//深度优先
void DfsOut()
{
cout << "DFS" << endl;
InitVisited();//初始化遍历数组
DFS(fgraph, 0);//深度优先,从0开始
cout << endl;
}
private:
MGraph mgraph;//邻接矩阵
FGraph *fgraph;//邻接表
string verx;//顶点
string weight;//权重
string edges[MAX_N];//边
int Tedges;//边数
stringstream sstr;//转换
int visited[MAX_N];

//搜索下标
int location(MGraph mg, char index)
{
for (int i = 0; i < mg.Tvertexs; i++)
{
if (mg.vert[i].verxname == index)//顶点名称匹配
{
return i;//返回位置
}
}
return -1;
}

//深度优先
void DFS(FGraph *fg, int versname)
{
Anode *p;
visited[versname] = 1;//定义为已遍历
cout << versname << ends;//输出顶点名称
p = fg->adjList[versname].firstAnode;
while (p != NULL)
{
if (visited[p->vesname] == INF)//未访问
{
DFS(fg, p->vesname);//递归遍历
}
p = p->nextAnode;//下一条边
}
}

//广度优先
void BFS(FGraph *fg, int versname)
{
Anode *p;
int queue[MAX_N], front = 0, rear = 0;
int w;
cout << versname << ends;//输出顶点名称
visited[versname] = 1;//定义为已遍历
rear = (rear + 1) % MAX_N;//尾加向后移动
queue[rear] = versname;//当前顶点名称为尾
while (front != rear)//非空
{
front = (front + 1) % MAX_N;//头向后移动
w = queue[front];//记录暂定开始顶点名称
p = fgraph->adjList[w].firstAnode;//该顶点下一位
while (p != NULL)
{
if (visited[p->vesname] == INF)//未访问
{
cout << p->vesname << ends;//输出
visited[p->vesname] = 1;//定义已访问
rear = (rear + 1) % MAX_N;//向后
queue[rear] = p->vesname;//从新赋值为当前顶点信息
}
p = p->nextAnode;//下一条边
}
}
cout << endl;
}
};
int main()
{
Graph g;
g.getInfo("data");//打开文件
g.CreateGraphMatrix();//创建图
g.display();//临接矩阵输出
g.MatTranToList();//邻接矩阵转换为邻接表
g.disp();//邻接表输出
g.DfsOut();//深度优先
g.BfsOut();//广度优先
return 0;
}



<span style="font-size:18px;">测试结果:</span>
<span style="font-size:18px;"><img src="http://img.blog.csdn.net/20160102205650049?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="" />
</span>
<span style="font-size:18px;">
</span>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: