c++实现图的构建与遍历
// 图.cpp: 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include<iostream>
#define size 6
using namespace std;
int matrix[size][size] = { { 0,1,1,0,0,1 },
{ 1,0,0,0,1,0 },
{ 1,0,0,0,0,1 },
{ 0,0,0,0,1,0 },
{ 0,1,0,1,0,0 },
{ 1,0,1,0,0,0 } };
int name[size] = { 11, 22, 33, 44, 55, 66 };
struct node
{
int data;
node *next;
};
class graph
{
private:
int i, j;
int nodenum;
int **edge;
node *data, *newnode, *searchp;
char *nodename;
bool *visited;
public :
graph(int matrix[][size], int nodenum, int *nodename);
~graph() {};
void visit(int data);
void create(); //构建邻接表
void showAdjacencyMatrix(); //显示邻接矩阵
void showAdjacencyTable(); //显示邻接表
void TDFSTraverse(int vertex); //深度优先遍历
void TBFSTraverse(int vertex); //广度优先遍历
};
graph::graph(int matrix[][size], int node_num, int *node_name)
{
nodenum = node_num;
edge = new int*[nodenum];
for (int i = 0; i < nodenum; i++)
edge[i] = new int[nodenum];
for (i = 0; i < nodenum; i++)
{
for (j = 0; j < nodenum; j++)
{
edge[i][j] = matrix[i][j];
}
}
nodename = new char[nodenum];
for (i = 0; i < nodenum; i++)
nodename[i] = node_name[i];
visited = new bool[nodenum];
for (i = 0; i < nodenum; i++)
visited[i] = false;
create();
}
void graph::create()
{
data = new node[nodenum];
for (i = 0; i < nodenum; i++)
{
data[i].data = nodename[i];
data[i].next = NULL;
searchp = &data[i];
for (j = 0; j < nodenum; j++)
{
if (edge[i][j] == 1)
{
newnode = new node;
newnode->data = j;
newnode->next = NULL;
searchp->next = newnode;
searchp = searchp->next;
}
}
}
}
void graph::showAdjacencyMatrix()
{
cout << "邻接矩阵为" << endl;
for (i = 0; i < nodenum; i++)
{
for (j = 0; j < nodenum; j++)
cout << edge[i][j] << " ";
cout << endl;
}
}
void graph::showAdjacencyTable()
{
cout << "邻接表为:" << endl;
for (i = 0; i < nodenum; i++)
{
searchp = &data[i];
while (searchp != NULL)
{
cout << searchp->data << "->";
searchp = searchp->next;
}
cout << endl;
}
}
void graph::visit(int data)
{
cout << data << " ";
}
void graph::TDFSTraverse(int vertex) //启栈便于回溯用
{
cout << "深度优先遍历如下:" << endl;
int stack[size], top = 0, count = 0;//栈结构初始化
bool *visited = new bool[nodenum];
for (i = 0; i < nodenum; i++)
visited[i] = false; //标记图的结点被访问情况
while (count < nodenum)
{
visit(vertex);
visited[vertex] = true;
stack[top] = vertex;
top++;
count++; //初始遍历结点进栈
if (count == nodenum)
break;
while (visited[vertex])
{
for (i = 0; i < nodenum //循环找出是否有未访问完的邻接点
&& (visited[i]
|| matrix[vertex][i] == 0); i++);
if (i == nodenum) //当前顶点vertex的所有邻接点都已访问完了
{
if (top != 0)
{
top--; //此时vertex正是栈顶,应先出栈
if (top != 0)
{
vertex = stack[top];
top--;
}
else //若栈已空,则需从头开始寻找新的、未访问过的顶点
{
for (vertex = 0; vertex < nodenum && visited[vertex]; vertex++);
}
}
else //若栈已空,则需从头开始寻找新的、未访问过的顶点
{
for (vertex = 0; vertex < nodenum && visited[vertex]; vertex++);
}
}
else //找到新的顶点应更新当前访问的顶点vertex
vertex = i;
}
}
delete[]visited;
}
void graph::TBFSTraverse(int vertex)
{
cout << "广度优先遍历如下:" << endl;
//使用环队列
int queue[size], count = 0, num = 0, front = 0, rear = 0; //队列初始化
//count用于统计已遍历过的顶点数
bool *visited = new bool[nodenum];
for (i = 0; i < nodenum; i++)
visited[i] = false; //标记图的结点被访问情况
queue[rear] = vertex;
rear = (rear + 1) % size;
num++; //遍历初始顶点进队
visit(vertex);
visited[vertex] = true;
count++;
while (count < nodenum)
{
if (num != 0) //队列不空
{
vertex = queue[front];
front = (front + 1) % size;
num--; //出队
}
else
{
for (vertex = 0; vertex < nodenum && visited[vertex]; vertex++);
visit(vertex);
visited[vertex] = true;
count++;
if (count == nodenum) //没有未被访问的邻接点
return;
queue[rear] = vertex;
rear = (rear + 1) % size; //进队
num++;
}
//代码走到这里,vertex是已经访问过的顶点
for (int i = 0; i < nodenum; i++)
{
if (!visited[i] && matrix[vertex][i] != 0) //未被访问且是vertex的邻接点
{
visit(i);
visited[i] = true;
count++;
if (count == nodenum)
return;
queue[rear] = i;
rear = (rear + 1) % size;
num++; //进队
}
}
}
delete[]visited;
}
int main()
{
graph g(matrix, 6, name);
g.showAdjacencyMatrix();
g.showAdjacencyTable();
g.TDFSTraverse(0);
cout << endl;
g.TBFSTraverse(0);
cout << endl;
system("pause");
return 0;
}