-
图的建立有两种方式,一种是邻接矩阵,也就是顺序存储。另一种则是邻接表
在遍历过程中我们需要有一个数组,用来标记结点是否被调用过,我们称它为visited数组。
我们需要初始化一个二维矩阵edge[i][j],用来存储边的集合,含义为第i个结点与第j个结点之间有边。
其次我们在创建一个存储顶点的数组,是一个string类型的数组
//构造函数
Graph::Graph(string arry[], int n, int e) {
int i, j;
// int k;
vertexnumber = n;
edgenumber = e;
for ( i = 0; i < vertexnumber; i++) { //初始化vertexnumber数组
vertexarry[i] = arry[i];
}
for ( i = 0; i < vertexnumber; i++) {
for ( j = 0; j < vertexnumber; j++) {
edge[i][j] = 0;
}
}
//偷个懒
edge[0][1] = edge[1][0] = 1;
edge[0][3] = edge[3][0] = 1;
edge[3][4] = edge[4][3] = 1;
edge[4][5] = edge[5][4] = 1;
edge[2][3] = edge[3][2] = 1;
edge[2][5] = edge[5][2] = 1;
edge[1][5] = edge[5][1] = 1;
}
-
对于邻接表存储(链式存储)
需要两个结构体,其中一个边集,一个顶点集.
在类中定义一个结构体类型的数组,这个数组长度=2*n-1,初始化边集、顶点集数组。
struct EdgeNode {//这是一个有关边集数组的结点
int adjvex;
EdgeNode* next;
};
struct VertexNode {//这是一个有关顶点集数组的结点
string vertex;
EdgeNode* firstedge;//每一个EdgeNode类型数组的头指针
};
//构造函数
ADGraph::ADGraph(string a[], int n, int e) {
vertexnumber = n;
edgenumber = e;
int i, j, k;
EdgeNode* s = NULL;
for ( i = 0; i < vertexnumber; i++) {//初始化顶点集数组
adjlist[i].vertex = a[i];
adjlist[i].firstedge = NULL;
}
for ( k = 0; k < edgenumber; k++) {//初始化边集数组
cin >> i >> j;
s = new EdgeNode;
s->adjvex = j;
s->next = adjlist[i].firstedge;
adjlist[i].firstedge = s;
}
}
对于深度、广度遍历方法。深度遍历调用递归算法,广度遍历方法则是调用队列。
-
深度遍历方法:
//深度优先遍历
void Graph::DFTraverse(int v) {
cout << vertexarry[v]<<" ";
visited1[v] = 1;//标记以访问的结点
for (int i = 0; i < vertexnumber; i++) {
if (edge[v][i] == 1 && visited1[i] == 0) {
DFTraverse(i);
}
}
}
-
广度优先遍历
//广度优先遍历
void Graph::BFTraverse(int v){
int Queue[10];
int front=-1,rear=-1,w,i;
cout<<vertexarry[v]<<" ";
visited2[v]=1;
Queue[++rear]=v; //入队
while(front!=rear){
w=Queue[++front]; //出队
for( i=0;i<vertexnumber;i++){
if(edge[w][i]==1 && visited2[i]==0){//第w结点与第i结点有边且第i个结点没有被访问过。
cout<<vertexarry[i]<<" ";
visited2[i]=1;
Queue[++rear]=i;
}
}
}
}
1 ### 邻接矩阵完整代码
//邻接矩阵建立图
#include <iostream>
using namespace std;
class Graph {
private:
int vertexnumber, edgenumber;
string vertexarry[10];//结点类型的顶点变量名数组
int edge[10][10];//边集数组
int visited1[10] = {0};//用来作为访问的标志
int visited2[10] = {0};//用来作为访问的标志
public:
Graph(string arry[], int n, int e); //构造函数,传入顶点数据、顶点个数、边的个数
~Graph();//析构函数
void DFTraverse(int v);//深度优先遍历函数
void BFTraverse(int v);//广度优先遍历函数
};
//构造函数
Graph::Graph(string arry[], int n, int e) {
int i, j;
// int k;
vertexnumber = n;
edgenumber = e;
for ( i = 0; i < vertexnumber; i++) { //初始化vertexnumber数组
vertexarry[i] = arry[i];
}
for ( i = 0; i < vertexnumber; i++) {
for ( j = 0; j < vertexnumber; j++) {
edge[i][j] = 0;
}
}
edge[0][1] = edge[1][0] = 1;
edge[0][3] = edge[3][0] = 1;
edge[3][4] = edge[4][3] = 1;
edge[4][5] = edge[5][4] = 1;
edge[2][3] = edge[3][2] = 1;
edge[2][5] = edge[5][2] = 1;
edge[1][5] = edge[5][1] = 1;
}
//析构函数
Graph::~Graph() {
cout << "删除成功!" << endl;
}
//深度优先遍历
void Graph::DFTraverse(int v) {
cout << vertexarry[v]<<" ";
visited1[v] = 1;
for (int i = 0; i < vertexnumber; i++) {
if (edge[v][i] == 1 && visited1[i] == 0) {
DFTraverse(i);
}
}
}
//广度优先遍历
void Graph::BFTraverse(int v){
int Queue[10];//队列
int front=-1,rear=-1,w,i;
cout<<vertexarry[v]<<" ";
visited2[v]=1;
Queue[++rear]=v;//入队
while(front!=rear){
w=Queue[++front];
for( i=0;i<vertexnumber;i++){
if(edge[w][i]==1 && visited2[i]==0){
cout<<vertexarry[i]<<" ";
visited2[i]=1;
Queue[++rear]=i;
}
}
}
}
int main() {
string arry[6] = {"v0", "v1", "v2", "v3", "v4", "v5"}; //用来存储每个结点的变量名
Graph g(arry, 6, 7);
cout<<"深度优先遍历:";
g.DFTraverse(0);//深度遍历
cout<<endl;
cout<<"广度优先遍历:";
g.BFTraverse(0);//广度遍历
cout<<endl;
return 0;
}
2 ### 邻接表完整代码
//邻接表建立图
#include <iostream>
using namespace std;
struct EdgeNode {//这是一个有关边集数组的结点
int adjvex;
EdgeNode* next;
};
struct VertexNode {//这是一个有关顶点集数组的结点
string vertex;
EdgeNode* firstedge;
};
class ADGraph {
private:
int vertexnumber, edgenumber;
VertexNode adjlist[10];
int visited1[10] = {0};
int visited2[10] = {0};
int Queue[10];
public:
ADGraph(string a[], int n, int e); //构造函数
~ADGraph();//析构函数
void DFTraverse(int v);//深度遍历
void BFTraverse(int v);//广度遍历
};
//构造函数
ADGraph::ADGraph(string a[], int n, int e) {
vertexnumber = n;
edgenumber = e;
int i, j, k;
EdgeNode* s = NULL;
for ( i = 0; i < vertexnumber; i++) {
adjlist[i].vertex = a[i];
adjlist[i].firstedge = NULL;
}
for ( k = 0; k < edgenumber; k++) {
cin >> i >> j;
s = new EdgeNode;
s->adjvex = j;
s->next = adjlist[i].firstedge;
adjlist[i].firstedge = s;
}
}
//析构函数
ADGraph::~ADGraph() {
EdgeNode *p = NULL;
EdgeNode *q = NULL;
for (int i = 0; i < vertexnumber; i++) {
p = q = adjlist[i].firstedge;
while (p != NULL) {
p = p->next;
delete q;
q = p;
}
}
}
//深度优先
void ADGraph::DFTraverse(int v) {
int j;
EdgeNode* p = NULL;
cout << adjlist[v].vertex << " ";
visited1[v] = 1;
p = adjlist[v].firstedge;
while (p != NULL) {
j = p->adjvex;
if (visited1[j] == 0) {
DFTraverse(j);
}
p = p->next;
}
}
//广度优先遍历
void ADGraph::BFTraverse(int v) {
int w, j;
int front = -1, rear = -1;
EdgeNode*p = NULL;
cout << adjlist[v].vertex << " ";
visited2[v] = 1;
Queue[++rear] = v;
while (front != rear) {
w = Queue[++front];
p = adjlist[w].firstedge;
while (p != NULL) {
j = p->adjvex;
if (visited2[j] == 0) {
cout << adjlist[j].vertex << " ";
visited2[j] = 1;
Queue[++rear] = j;
}
p = p->next;
}
}
}
int main() {
string w[5] = {"v0", "v1", "v2", "v3", "v4"};
ADGraph a(w, 5, 6);
cout << "深度优先遍历:";
a.DFTraverse(0);
cout << endl;
cout << "广度优先遍历:";
a.BFTraverse(0);
return 0;
}