题目描述

利用邻接矩阵存储结构,完成深度优先遍历和广度优先遍历算法。已知部分代码如下(勿改动),只需完成深度遍历DFSTraverse和广度遍历BFSTraverse即可。
#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;
}
//Class MGraph
const int MaxSize=20; //图中最多顶点个数
int visited[MaxSize]; //访问标志数组(0表示未访问,1表示已访问)
template
class MGraph
{
public:
MGraph(T a[],int n,int e); //构造函数,初始化具有n个顶点,e条边的图
void DispMGraph(); //输出图中顶点值和矩阵值

void DFSTraverse(int v); // 从v顶点出发深度优先遍历图(一个连通子图)
void BFSTraverse(int v); // 从v顶点出发广度优先遍历图(一个连通子图)
private:
T vertex[MaxSize]; //存放图中顶点信息的数组
int arc[MaxSize][MaxSize]; //存放图中顶点关系(边)的数组
int vertexNum,arcNum; //图的顶点数和边数
};
//构造一个邻接矩阵存储的无向图
template
MGraph::MGraph(T a[], int n, int e)
{
vertexNum=n; //顶点数
arcNum=e; //边数
int i,j,k;
for (i=0; ivertex[i]=a[i]; //顶点值
for (i=0; ifor (j=0; jarc[i][j]=0;
for (k=0; k{
cin>>i>>j; //输入各条边依附的两个顶点的序号
arc[i][j]=1; //置有边标志
arc[j][i]=1;
}
}
//输出图中所有顶点信息,和边信息
template
void MGraph::DispMGraph( )
{
int i,j;
cout<<” “;
for(i=0;icout<cout<for(i=0;i{
cout<for(j=0;jcout<cout<}
}
//在此处实现深度优先遍历算法

//在此处实现广度优先遍历算法

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; //输入顶点个数和边个数
MGraph G(a,n,e);
G.DispMGraph();
for(i=0;ivisited[i]=0;
cout<<”DFS:”;
G.DFSTraverse(0);
cout<for(i=0;ivisited[i]=0;
cout<<”BFS:”;
G.BFSTraverse(0);
return 0;
}

输入

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

输出

样例输入

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

样例输出

A B C D E F A 0 1 0 1 0 0 B 1 0 1 0 0 1 C 0 1 0 0 1 0 D 1 0 0 0 0 1 E 0 0 1 0 0 1 F 0 1 0 1 1 0 DFS:A B C E F D BFS:A B D C F E

提示

来源

提交

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