OJ有向图的邻接表表示法验证程序 题目编号:516
用邻接表表示有向图,完成图的创建、图的深度优先遍历、图的广度优先遍历操作。其中图的顶点信息是字符型,图中顶点序号按字符顺序排列,边的输入按照边的顶点序号从小到大的顺序排列,如下图的边的输入顺序为0 1,0 2,0 3,1 2,1 3,2 4,3 4共七条边,邻接表的边结点采用头插法。(无图)
输入描述
第一行输入两个值,第一个是图中顶点的个数,第二个是图中边的条数
第二行输入各顶点的信息,即输入每个顶点字符
第三行开始输入每条边,每条边的形式为两个顶点的序号,中间以空格隔开,输入完一条边换行
输出描述
首先输出图的顶点信息,输出完毕换行
接着输出图的邻接表,格式为首先输出第一个顶点,接着输出该顶点的所有的临界点的序号,换行,然后输出下一个顶点及邻接点,以此类推
接下来一行输出从图的第一个顶点开始进行深度优先遍历的序列,中间以空格隔开,输出完毕换行
最后一行输出从图的第一个顶点开始进行广度优先遍历的序列,中间以空格隔开,输出完毕换行
输入样例
5 7
A B C D E
0 1
0 2
0 3
1 2
1 3
2 4
3 4
输出样例
A B C D E
A 3 2 1
B 3 2
C 4
D 4
E
A D E C B
A D C B E
#include<iostream>
using namespace std;
const int MaxSize = 20;
struct EdgeNode//保存边表结点其中有下一个结点的下表和指向下一个结点的指针
{
int adjvex;//邻接点域
EdgeNode *next;//下一结点
};
struct VertexNode
{
char vertex; //保存顶点
EdgeNode *firstEdge; //指针域,指向下一个结点
};
class AlGraph
{
public:
AlGraph();
~AlGraph();
void DETraverse(int v); //深度优先遍历
void BFTraverse(int v); //广度优先遍历
void BFTraverse1(int v); //如果广度遍历未全部遍历就遍历剩下的
void LinJie(int v);
void DEnoCross(); //遍历没有访问过的顶点
void show(); //输出顶点信息
int visited[MaxSize];
int EdgeNum,VertexNum; //保存顶点和边的个数
private:
VertexNode adjlist[MaxSize];
};
void AlGraph::VertexShowing()
{
for(int i = 0; i < VertexNum; i++)
{
cout << adjlist[i].vertex << " ";
}
}
void AlGraph::DEnoCross()
{
for(int i = 0; i < VertexNum; i++)
{
if(visited[i] == 0)
{
DETraverse(i); //如果没有访问过,就重新进行深度遍历
}
}
}
void AlGraph::LinJie(int v) //输出邻接表,以及该顶点的所有邻接点序号
{
for (int i = 0; i < VertexNum; i++)
{
visited[i] = 0;
}
EdgeNode *p = NULL;
for(int i = 0;i < VertexNum; i++)
{
cout << adjlist[i].vertex << " ";
p = adjlist[i].firstEdge;
while(p != NULL)
{
cout << p->adjvex << " ";
p = p->next;
}
cout << endl;
}
}
AlGraph::AlGraph()
{
int x, y; //用来保存边
EdgeNode *s = NULL;
cin >> VertexNum >> EdgeNum; //输入边数和顶点数
for(int i =0;i < VertexNum; i++) //循环输入顶点
{
cin >> adjlist[i].vertex;
adjlist[i].firstEdge = NULL;
visited[i] = 0;
}
for(int j = 0; j < EdgeNum; j++) //循环输入边
{
cin >> x >> y;
s = new EdgeNode; //将与顶点相关的边用首插法构建成一个链表
s->adjvex = y;
s->next = adjlist[x].firstEdge;
adjlist[x].firstEdge = s;
}
}
AlGraph::~AlGraph() //循环释放顶点资源
{
EdgeNode *p = NULL, *q = NULL;
for(int i = 0; i < VertexNum; i++)
{
p = q = adjlist[i].firstEdge;
while(p != NULL)
{
p = p->next;
delete q;
q = p;
}
}
}
void AlGraph::DETraverse(int v) //深度优先遍历:是通过链表来遍历
{
int j;
EdgeNode *p = NULL;
cout << adjlist[v].vertex << " ";
visited[v] = 1;
p = adjlist[v].firstEdge;
while(p != NULL)
{
j = p->adjvex;
if(visited[j] == 0)
{
DETraverse(j);
}
p = p->next;
}
}
void AlGraph::BFTraverse(int v) //广度优先遍历是通过数组来实现
{
for(int i = 0; i < VertexNum; i++)
{
visited[i] = 0;
}
EdgeNode *p = NULL;
char Q[MaxSize]; //用来保存待访问的顶点
int w,j;
int rear,front;
rear = front = -1;
cout << adjlist[v].vertex << " ";
visited[v] = 1;
Q[++rear] = v;
while(rear != front)
{
w = Q[++front];
p = adjlist[w].firstEdge;
while(p != NULL)
{
j = p->adjvex;
if(visited[j] == 0)
{
cout << adjlist[j].vertex << " ";
visited[j] = 1;
Q[++rear] = j;
}
p = p->next;
}
}
front = rear = -1;
}
void AlGraph::BFTraverse1(int v) //广度优先遍历是通过数组来实现
{
EdgeNode *p = NULL;
char Q[MaxSize]; //用来保存待访问的顶点
int w,j;
int rear,front;
rear = front = -1;
cout << adjlist[v].vertex << " ";
visited[v] = 1;
Q[++rear] = v;
while(rear != front)
{
w = Q[++front];
p = adjlist[w].firstEdge;
while(p != NULL)
{
j = p->adjvex;
if(visited[j] == 0)
{
cout << adjlist[j].vertex << " ";
visited[j] = 1;
Q[++rear] = j;
}
p = p->next;
}
}
front = rear = -1;
}
int main()
{
AlGraph A;
A.show();
cout<<endl;
A.LinJie(0);
A.DETraverse(0);
A.DEnoCross();
cout << endl;
A.BFTraverse(0);
for(int i = 0; i < A.VertexNum; i++)
{
if(A.visited[i] == 0)
{
A.BFTraverse1(i);
// cout<<A.visited[i];
}
}
}