题目描述

已知邻接表存储的无向图的部分代码如下,请补充完成深度优先、广度优先遍历算法。
//graphmain.cpp
#include
#include
using namespace std;
//循环队列类
const int QueueSize=100; //循环队列的最大长度
template //定义模板类CirQueue
class CirQueue
{
public:
CirQueue( ); //构造函数,置空队
~ CirQueue( ); //析构函数
void EnQueue(T x); //将元素x入队
T DeQueue( ); //将队头元素出队
T GetQueue( ); //取队头元素(并不删除)
bool Empty( ); //判断队列是否为空
bool Full();
private:
T data[QueueSize]; //存放队列元素的数组
int front, rear; //队头和队尾指针,分别指向队头元素的前一个位置和队尾元素的位置
};
//功 能:初始化空队列
template
CirQueue::CirQueue( )
{
front=rear=0;
}
// 功 能:销毁队列
template
CirQueue::~CirQueue( )
{
}
//功 能:元素x入队
template
void CirQueue::EnQueue(T x)
{
if (Full()) throw “Overflow”;
rear=(rear+1) % QueueSize; //队尾指针在循环意义下加1
data[rear]=x; //在队尾处插入元素
}
//功 能:队头元素出队,返回值为出队元素
template
T CirQueue::DeQueue( )
{
if (Empty()) throw “Downflow”;
front=(front+1) % QueueSize; //队头指针在循环意义下加1
return data[front]; //读取并返回出队前的队头元素,注意队头指针
}
//指向队头元素的前一个位置
// 功 能:获取队头元素
template
T CirQueue::GetQueue( )
{
int i;
if (Empty()) throw “Downflow”;
i=(front+1) % QueueSize; //注意不要给队头指针赋值
return data[i];
}
// 功 能:判断队列是否为空,若空返回true,否则返回false
template
bool CirQueue::Empty( )
{
return front==rear;
}
//功 能:判断队列是否满,若满返回true,否则false
template
bool CirQueue::Full()
{
return (rear+1)%QueueSize==front;
}
const int MaxSize=20; // 顶点个数的最大值
int visited[MaxSize]; //访问标志数组(0表示未访问,1表示已访问)
//定义边表结点
struct ArcNode
{
int adjvex; //邻接点的序号
ArcNode next; //指向下一个边结点的指针
};
//定义顶点表结点
template
struct VertexNode
{
T vertex; //顶点的名称
ArcNode
firstedge; //指向第一个边表结点的头指针
};
//邻接表类
template
class ALGraph
{
public:
ALGraph(T a[ ], int n, int e); //构造函数,初始化一个有n个顶点e条边的图
~ALGraph(); //析构函数,释放邻接表中各边表结点的存储空间
void DispALGraph(); //输出邻接表
int Count( ); //计算连通分量个数,返回值为连通分量的个数(请大家自己测试)
void DFSTraverse(int v); //深度优先遍历图
void BFSTraverse(int v); //深度优先遍历图
private:
VertexNode adjlist[MaxSize]; //存放顶点表的数组
int vertexNum, arcNum; //图的顶点数和边数
};
/
前置条件:图不存在
输 入:无
功 能:图的初始化
输 出:无
后置条件:得到一个无向图
/
template
ALGraph::ALGraph(T a[ ], int n, int e)
{
arcNum = e; //边数
vertexNum=n; //顶点数
int i,j;
for (i=0; i{
adjlist[i].vertex = a[i];
adjlist[i].firstedge = NULL;
}
for (int k=0; k{
cin>>i>>j; //输入边所依附的两个顶点的序号
ArcNode
s=new ArcNode;
s->adjvex=j; //生成一个边表结点s
s->next=adjlist[i].firstedge; //将结点s插入到i号表的头结点之后
adjlist[i].firstedge=s;
s=new ArcNode;
s->adjvex=i; //生成一个边表结点s
s->next=adjlist[j].firstedge; //将结点s插入到j号表的头结点之后
adjlist[j].firstedge=s;
}
}
/ 前置条件:图已存在
输 入:无
功 能:销毁图
输 出:无
后置条件:释放图所占用的存储空间
/
template
ALGraph::~ALGraph( )
{
for (int i=0; i{
ArcNode p=adjlist[i].firstedge;
while (p!=NULL) //循环删除
{
adjlist[i].firstedge=p->next;
delete p; //释放结点空间
p=adjlist[i].firstedge;
}
}
}
/

前置条件:图已存在
输 入:无
功 能:输出图中所有顶点及边的数据信息
输 出:图中所有顶点及边的数据信息
后置条件:图保持不变
/
template
void ALGraph::DispALGraph( )
{
int i;
ArcNode *p;
cout<<”图的邻接表:\n”;
for(i=0;icout<for(p=adjlist[i].firstedge;p;p=p->next)
cout<adjvex<<” “; //输出i号顶点的邻接点的序号
cout<}
}
template
int ALGraph::Count( )
{
int i,n=0;
for(i=0;ifor(i=0;iif(!visited[i]){
n++;
BFSTraverse(i); //利用深度优先或广度优先遍历算法均可
}
}
return n;
}
//在下面完成深度优先、广度优先遍历算法
int main()
{
string a[]={“A”,”B”,”C”,”D”,”E”,”F”,”G”,”H”,”I”,”J”,”K”,”L”,”M”,”N”}; //顶点信息
int i,n,e;
cin>>n>>e; //输入顶点个数和边个数
ALGraph G(a,n,e);
G.DispALGraph();
for(i=0;ivisited[i]=0;
cout<<”DFS:”;
G.DFSTraverse(0);
cout<for(i=0;ivisited[i]=0;
cout<<”BFS:”;
G.BFSTraverse(0);
// cout<<”\n连通分量个数:”;
// cout<return 0;
}

输入

第一行为顶点个数和边的条数:6 7
第二行为各条边所对应的顶点序号:0 1 0 3 1 2 1 5 2 4 3 5 4 5

输出

因为构造函数中各条边所对应的边表结点采用头插法插入到表头结点之后,因此输入0 1 0 3,0号链表后为3 1序列,其它亦如此。
图的邻接表:
0 A 3 1
1 B 5 2 0
2 C 4 1
3 D 5 0
4 E 5 2
5 F 4 3 1
DFS:A D F E C B
BFS:A D B F C E

样例输入

6 7 0 1 0 3 1 2 1 5 2 4 3 5 4 5

样例输出

Graph adjlist: 0 A 3 1 1 B 5 2 0 2 C 4 1 3 D 5 0 4 E 5 2 5 F 4 3 1 DFS:A D F E C B BFS:A D B F C E

提示

来源

提交

  1. package Q1026;
  2. import java.util.Scanner;
  3. class CirQueue{
  4. Object[] queueElem;
  5. int front;
  6. int rear;
  7. int QueueSize=5;
  8. public CirQueue(){
  9. front = rear = 0;
  10. queueElem = new Object[QueueSize];
  11. }
  12. public void clear(){
  13. front = rear = 0;
  14. }
  15. public boolean isEmpty(){
  16. return front == rear;
  17. }
  18. public int length(){
  19. return (rear-front+queueElem.length)% queueElem.length;
  20. }
  21. public boolean isFull(){
  22. return (rear+1) % QueueSize ==front;
  23. }
  24. public void EnQueue(Object x) throws Exception{
  25. if((rear+1)%queueElem.length==front){
  26. throw new Exception(" Overflow");
  27. }else{
  28. queueElem[rear] = x;
  29. rear = (rear+1)%queueElem.length;
  30. }
  31. }
  32. public Object DeQueue() throws Exception {
  33. if(front==rear){
  34. throw new Exception("Downflow");
  35. }else{
  36. Object t = queueElem[front];
  37. front = (front+1)%queueElem.length;
  38. return t;
  39. }
  40. }
  41. public Object GetQueue() throws Exception {
  42. if(front==rear){
  43. throw new Exception("Downflow");
  44. }else{
  45. Object t = queueElem[front];
  46. return t;
  47. }
  48. }
  49. }
  50. //图的接口
  51. interface IGraph {
  52. void createGraph();// 创建一个图
  53. int getVexNum(); // 返回顶点数
  54. int getArcNum();// 返回边数
  55. Object getVex(int v) throws Exception;// 返回v表示结点的值, 0 <= v < vexNum
  56. int locateVex(Object vex);// 给定顶点的值vex,返回其在图中的位置,如果图中不包含此顶点,则返回-1
  57. int firstAdjVex(int v) throws Exception; // 返回v的第一个邻接点,若v没有邻接点,则返回-1,其中0≤v<vexNum
  58. int nextAdjVex(int v, int w) throws Exception;// 返回v相对于w的下一个邻接点,若w是v的最后一个邻接点,则返回-1,其中0≤v,
  59. // w<vexNum
  60. }
  61. class ArcNode {
  62. public int adjVex;
  63. public int value;
  64. public ArcNode nextArc;
  65. public ArcNode() {
  66. this(-1, 0, null);
  67. }
  68. public ArcNode(int adjVex) {
  69. this(adjVex, 0, null);
  70. }
  71. public ArcNode(int adjVex, int value) {
  72. this(adjVex, value, null);
  73. }
  74. public ArcNode(int adjVex, int value, ArcNode nextArc) {
  75. this.value = value;
  76. this.adjVex = adjVex;
  77. this.nextArc = nextArc;
  78. }
  79. }
  80. class VNode {
  81. public Object data;
  82. public ArcNode firstArc;
  83. public VNode() {
  84. this(null, null);
  85. }
  86. public VNode(Object data) {
  87. this(data, null);
  88. }
  89. public VNode(Object data, ArcNode firstArc) {
  90. this.data = data;
  91. this.firstArc = firstArc;
  92. }
  93. }
  94. class ALGraph implements IGraph {
  95. private int vexNum, arcNum;
  96. private VNode[] vexs;
  97. private static boolean[] visited;// 访问标志数组
  98. public ALGraph() {
  99. this(0, 0, null);
  100. }
  101. public ALGraph(int vexNum, int arcNum, VNode[] vexs) {
  102. this.vexNum = vexNum;
  103. this.arcNum = arcNum;
  104. this.vexs = vexs;
  105. }
  106. public void createGraph() {
  107. Scanner sc = new Scanner(System.in);
  108. vexNum = sc.nextInt();
  109. arcNum = sc.nextInt();
  110. vexs = new VNode[vexNum];
  111. String Node[]={"A","B","C","D","E","F","G","H","I","J","K","L","M","N"}; //顶点信息
  112. for (int v = 0; v < vexNum; v++)
  113. vexs[v] = new VNode(Node[v]);
  114. for (int k = 0; k < arcNum; k++) {
  115. int v = sc.nextInt();// 弧尾
  116. int u = sc.nextInt();// 弧头
  117. int value = 1;
  118. addArc(v, u, value);
  119. addArc(u, v, value);
  120. }
  121. }
  122. public void addArc(int v, int u, int value) {
  123. ArcNode arc = new ArcNode(u, value);
  124. arc.nextArc=vexs[v].firstArc;
  125. vexs[v].firstArc=arc;
  126. }
  127. public int getVexNum() {
  128. return vexNum;
  129. }
  130. public int getArcNum() {
  131. return arcNum;
  132. }
  133. public int locateVex(Object vex) {
  134. for (int v = 0; v < vexNum; v++)
  135. if (vexs[v].data.equals(vex))
  136. return v;
  137. return -1;
  138. }
  139. public VNode[] getVexs() {
  140. return vexs;
  141. }
  142. public Object getVex(int v) throws Exception {
  143. if (v < 0 && v >= vexNum)
  144. throw new Exception("第" + v + "个顶点不存在!");
  145. return vexs[v].data;
  146. }
  147. public int firstAdjVex(int v) throws Exception {
  148. if (v < 0 && v >= vexNum)
  149. throw new Exception("第" + v + "个顶点不存在!");
  150. VNode vex = vexs[v];
  151. if (vex.firstArc != null)
  152. return vex.firstArc.adjVex;
  153. else
  154. return -1;
  155. }
  156. public int nextAdjVex(int v, int w) throws Exception {
  157. if (v < 0 && v >= vexNum)
  158. throw new Exception("第" + v + "个顶点不存在!");
  159. VNode vex = vexs[v];
  160. ArcNode arcvw = null;
  161. for (ArcNode arc = vex.firstArc; arc != null; arc = arc.nextArc)
  162. if (arc.adjVex == w) {
  163. arcvw = arc;
  164. break;
  165. }
  166. if (arcvw != null && arcvw.nextArc != null)
  167. return arcvw.nextArc.adjVex;
  168. else
  169. return -1;
  170. }
  171. public void setArcNum(int arcNum) {
  172. this.arcNum = arcNum;
  173. }
  174. public void setVexNum(int vexNum) {
  175. this.vexNum = vexNum;
  176. }
  177. public void setVexs(VNode[] vexs) {
  178. this.vexs = vexs;
  179. }
  180. public void DFSTraverse() throws Exception {
  181. visited = new boolean[getVexNum()];
  182. for (int v = 0; v < getVexNum(); v++)
  183. // 访问标志数组初始化
  184. visited[v] = false;
  185. System.out.print("DFS:");
  186. for (int v = 0; v < getVexNum(); v++)
  187. if (!visited[v])// 对尚未访问的顶点调用DFS
  188. DFS(v);
  189. }
  190. private void DFS(int v) throws Exception {
  191. visited[v] = true;
  192. // 访问第v个顶点
  193. System.out.print(getVex(v).toString() + " ");
  194. for (int w = firstAdjVex(v); w >= 0; w = nextAdjVex(v, w))
  195. if (!visited[w])// 对v的尚未访问的邻接顶点w递归调用DFS
  196. DFS(w);
  197. }
  198. public void BFSTraverse() throws Exception {
  199. visited = new boolean[getVexNum()];// 访问标志数组
  200. for (int v = 0; v < getVexNum(); v++)
  201. // 访问标志数组初始化
  202. visited[v] = false;
  203. System.out.print("BFS:");
  204. for (int v = 0; v < getVexNum(); v++)
  205. if (!visited[v]) // v尚未访问
  206. BFS(v);
  207. }
  208. private void BFS(int v) throws Exception {
  209. visited[v] = true;
  210. System.out.print(getVex(v).toString() + " ");
  211. CirQueue Q = new CirQueue();// 辅助队列Q
  212. Q.EnQueue(v);// v入队列
  213. while (!Q.isEmpty()) {
  214. int u = (Integer) Q.DeQueue();// 队头元素出队列并赋值给u
  215. for (int w = firstAdjVex(u); w >= 0; w = nextAdjVex(u, w))
  216. if (!visited[w]) {// w为u的尚未访问的邻接顶点
  217. visited[w] = true;
  218. System.out.print(getVex(w).toString() + " ");
  219. Q.EnQueue(w);
  220. }
  221. }
  222. }
  223. void DispMGraph(){
  224. int i;
  225. ArcNode p;
  226. System.out.println("Graph adjlist:");
  227. for(i=0;i<vexNum;i++){
  228. System.out.print(i + " " +vexs[i].data + " ");
  229. p = vexs[i].firstArc;
  230. while(p!=null){
  231. System.out.print(p.adjVex + " ");
  232. p= p.nextArc;
  233. }
  234. System.out.println("");
  235. }
  236. }
  237. }
  238. public class Main {
  239. public static void main(String[] args) throws Exception {
  240. ALGraph a = new ALGraph();
  241. a.createGraph();
  242. a.DispMGraph();
  243. a.DFSTraverse();
  244. System.out.println("");
  245. a.BFSTraverse();
  246. }
  247. }