本科课程【数据结构与算法】实验5 - 广度优先搜索、二叉排序树的构造

x33g5p2x  于2022-03-21 转载在 其他  
字(5.1k)|赞(0)|评价(0)|浏览(559)

大家好,我是【1+1=王】, 热爱java的计算机(人工智能)渣硕研究生在读。
如果你也对java、人工智能等技术感兴趣,欢迎关注,抱团交流进大厂!!!
Good better best, never let it rest, until good is better, and better best.

近期会把自己本科阶段的一些课程设计、实验报告等分享出来,供大家参考,希望对大家有帮助。

博客更新至专栏【课程设计实验报告】:https://blog.csdn.net/weixin_43598687/category_11640051.html

一、 实验目的

  1. 掌握图的邻接表存储结构
  2. 实现图的广度优先搜索
  3. 掌握二叉排序树的链式存储结构
  4. 实现二叉排序树的构造

二、 实验内容

1. 实验任务

(1)建立一个无向连通图,用广度优先搜索(BFS)遍历
(2)输入一串数字,建立二叉排序树

2. 程序设计

1) 数据输入(输入哪些数据、个数、类型、来源、输入方式)
无向图的顶点数据(data)char字符型;
无向图的边关系(v1,v2)int 整型;
各边的权值(w)int 整型

二叉树的结点关键数(key)int整型

2) 数据存储(输入数据在内存中的存储)
采用new方法动态分配空间,以邻接表存储

采用new 动态分配空间,储存在*BinSearchTree中
3) 数据处理(说明处理步骤。若不是非常简单,需要绘制流程图)

①建立邻接表储存无向图
输入总顶点数和总边数;
建立顶点表(依次输入点的信息存入顶点表中,使每个表头节点的指针域初始化NULL)
创建邻接表(依次输入每条边依附的两个顶点,确定两个顶点的序号i和j,建立边节点,将此边节点分别插入到vi和vj对应的两个边链表的头部)
②BFS广度优先遍历
从某一顶点出发,首先依次访问该顶点的所有邻接节点,再依次访问该节点邻接节点的所有临街节点,直到所有节点被访问

①输入第一个数为根节点,之后输入的数如果小则做为左孩子(lchild),大则做为右孩子直到输入为-1,结束构造
②在二叉树中查找关键数key时,若二叉树T=NULL,查找失败;
若key=T->data.key,查找成功;
若keydata.key,则查找T所在节点的左子树;
若key>T->data.key,则查找T所在节点的右子树

4) 数据输出(贴图:程序运行结果截图。图幅大小适当,不能太大)

三、 实验环境

  1. 操作系统:WINDOWS 10
  2. 开发工具:VC++ 2013
  3. 实验设备:PC

源代码(C++实现)

图的广度优先搜索

  1. #include<iostream>
  2. #include <stdio.h>
  3. using namespace std;
  4. #define MaxVerNum 100
  5. #define MAX_QUEUE_LENGTH 100
  6. bool visited[MaxVerNum];
  7. typedef char VertexType;
  8. typedef struct VNode
  9. {
  10. VertexType data;
  11. ArcNode * firstarc;
  12. }VNode,AdjList[MaxVerNum];
  13. typedef struct ArcNode
  14. {
  15. int adjvex;
  16. struct ArcNode * nextarc;
  17. int info;
  18. }ArcNode;
  19. typedef struct
  20. {
  21. AdjList vertices;
  22. int vexnum, arcnum;
  23. }ALGraph;
  24. #define MAX_QUEUE_LENGTH 64 // 队列最大长度
  25. // 环形队列
  26. typedef struct Queue{
  27. int buffer[MAX_QUEUE_LENGTH]; // 队列缓冲区
  28. int begin; // 开始位置
  29. int end; // 结束位置
  30. int length; // 队列长度
  31. }Queue;
  32. void CreateALGraph(ALGraph &G);
  33. int LocateVex(ALGraph G, VertexType v);
  34. int NextAdjVex(ALGraph G, int u, int w);
  35. void InitQueue(Queue* pQ);
  36. int EnQueue(Queue* pQ, int Elem);
  37. int DeQueue(Queue* pQ);
  38. int QueueEmpty(Queue* pQ);
  39. void BFS(ALGraph G, int v);
  40. int main()
  41. {
  42. int n;
  43. cin >> n;
  44. ALGraph graph;
  45. CreateALGraph(graph);
  46. BFS(graph, n);
  47. system("pause");
  48. return 0;
  49. }
  50. /*
  51. *建立无向图的邻接表存储
  52. */
  53. void CreateALGraph(ALGraph &G)
  54. {
  55. int i, j, k;
  56. VertexType v1, v2;
  57. cout << "输入顶点数和边数:" << endl;
  58. cin >> G.vexnum >> G.arcnum;
  59. cout << "输入顶点数据:" << endl;
  60. for (i = 0; i < G.vexnum; i++)
  61. {
  62. cin >> G.vertices[i].data;
  63. G.vertices[i].firstarc = NULL;
  64. }
  65. cout << "输入各边关系:" << endl;
  66. for (k = 0; k < G.arcnum; k++)
  67. {
  68. cin >> v1 >> v2;
  69. i = LocateVex(G, v1);
  70. j = LocateVex(G, v2);
  71. ArcNode *p1 = new ArcNode;
  72. p1->adjvex = j;
  73. p1->nextarc = G.vertices[i].firstarc;
  74. G.vertices[i].firstarc = p1;
  75. ArcNode *p2 = new ArcNode;
  76. p1->adjvex = i;
  77. p1->nextarc = G.vertices[j].firstarc;
  78. G.vertices[j].firstarc = p2;
  79. }
  80. }
  81. /*
  82. 确定顶点号
  83. */
  84. int LocateVex(ALGraph G, VertexType v)
  85. {
  86. for (int i = 0; i < G.vexnum; i++)
  87. {
  88. if (v == G.vertices[i].data)
  89. return i;
  90. return -1;
  91. }
  92. }
  93. /*
  94. 功能:
  95. 初始化队列。
  96. 参数:
  97. pQ -- 队列指针
  98. */
  99. void InitQueue(Queue* pQ)
  100. {
  101. pQ->begin = pQ->end = 0;
  102. pQ->length = 0;
  103. }
  104. /*
  105. 功能:
  106. 将元素插入队尾。
  107. 参数:
  108. pQ -- 队列指针
  109. Elem -- 入队的元素
  110. 返回值:
  111. 如果插入成功返回入队元素的值。
  112. 如果插入失败返回 -1。
  113. */
  114. int EnQueue(Queue* pQ, int Elem)
  115. {
  116. //
  117. // 队列满,入队失败。
  118. //
  119. if (MAX_QUEUE_LENGTH == pQ->length)
  120. return -1;
  121. pQ->buffer[pQ->end] = Elem;
  122. pQ->end = (pQ->end + 1) % MAX_QUEUE_LENGTH;
  123. pQ->length++;
  124. return Elem;
  125. }
  126. /*
  127. 功能:
  128. 将队首元素出队
  129. 参数:
  130. pQ -- 队列指针
  131. 返回值:
  132. 如果出队成功返回出队元素的值。
  133. 如果出队失败返回 -1。
  134. */
  135. int DeQueue(Queue* pQ, int Elem)
  136. {
  137. //
  138. // 队列空,出队失败
  139. //
  140. if (QueueEmpty(pQ))
  141. return -1;
  142. Elem = pQ->buffer[pQ->begin];
  143. pQ->begin = (pQ->begin + 1) % MAX_QUEUE_LENGTH;
  144. pQ->length--;
  145. return Elem;
  146. }
  147. /*
  148. 功能:
  149. 判断队列是否为空。
  150. 参数:
  151. pQ -- 队列指针
  152. 返回值:
  153. 如果队列空返回 1(真)
  154. 如果队列非空返回 0(假)
  155. */
  156. int QueueEmpty(Queue* pQ)
  157. {
  158. return 0 == pQ->length ? 1 : 0;
  159. }
  160. /*
  161. BFS广度优先遍历
  162. */
  163. void BFS(ALGraph G, int v)
  164. {
  165. for (int i = 0; i < G.vexnum; i++)
  166. {
  167. visited[i] = false;
  168. }
  169. cout << v;
  170. visited[v] = true;
  171. Queue* Q;
  172. InitQueue(Q);
  173. EnQueue(Q, v);
  174. int u;
  175. while (!QueueEmpty(Q))
  176. {
  177. DeQueue(Q,u);
  178. for (int w = v; w >= 0; w = NextAdjVex(G, u, w))
  179. {
  180. if (!visited[w])
  181. {
  182. cout << w;
  183. visited[w] = true;
  184. EnQueue(Q, w);
  185. }
  186. }
  187. }
  188. }
  189. /*
  190. 下一条边
  191. */
  192. int NextAdjVex(ALGraph G, int u, int w)
  193. {
  194. ArcNode *p;
  195. p->adjvex = u;
  196. w = p->nextarc->adjvex;
  197. }

二叉排序树BFS的构造

  1. #include<iostream>
  2. using namespace std;
  3. typedef int KeyType; // 关键码字段类型
  4. typedef struct BinSearchNode{
  5. KeyType Key; // 节点的关键码字段
  6. struct BinSearchNode* lchild; // 左孩子指针
  7. struct BinSearchNode* rchild; // 右孩子指针
  8. }BinSearchNode, *BinSearchTree;
  9. bool Tree_Search(BinSearchTree T, KeyType key);
  10. BinSearchTree Tree_Insert(BinSearchTree T, int key);
  11. BinSearchTree Create(BinSearchTree T);
  12. void MiddleTravel(BinSearchTree);
  13. int main()
  14. {
  15. BinSearchTree pTree=NULL; // 二叉排序树指针
  16. Create(pTree);
  17. MiddleTravel(pTree);
  18. system("pause");
  19. return 0;
  20. }
  21. /*
  22. 寻找当前节点
  23. */
  24. bool Tree_Search(BinSearchTree T, KeyType key)
  25. {
  26. BinSearchTree p;
  27. p = T;
  28. while (p)
  29. {
  30. if (key == p->Key)
  31. return true;
  32. else
  33. p = (key < p->Key) ? (p->lchild) : (p->rchild);
  34. }
  35. return false;
  36. }
  37. /*
  38. 比较关键数大小
  39. */
  40. BinSearchTree Tree_Insert(BinSearchTree T, int key)
  41. {
  42. BinSearchTree p=T;
  43. BinSearchTree f=NULL, s;
  44. while (p != NULL)
  45. {
  46. f = p;
  47. if (key == p->Key)
  48. return T;
  49. p = (key < p->Key) ? (p->lchild) : (p->rchild);
  50. }
  51. s = new BinSearchNode;
  52. s->Key = key;
  53. s->lchild = NULL;
  54. s->rchild = NULL;
  55. if (T == NULL)
  56. return s;
  57. if (key < f->Key)
  58. f->lchild = s;
  59. else
  60. f->rchild = s;
  61. return T;
  62. }
  63. /*
  64. 创建树
  65. */
  66. BinSearchTree Create(BinSearchTree T)
  67. {
  68. KeyType key;
  69. T = NULL;
  70. cout << "输入节点关键数,以-1结束" << endl;
  71. cin >> key;
  72. while (key != -1)
  73. {
  74. Tree_Insert(T, key);
  75. cin >> key;
  76. }
  77. return T;
  78. }
  79. /*
  80. 中序遍历
  81. */
  82. void MiddleTravel(BinSearchTree T)
  83. {
  84. cout << "中序遍历为:";
  85. if (T != NULL)
  86. {
  87. MiddleTravel(T->lchild);
  88. cout << T->Key;
  89. MiddleTravel(T->rchild);
  90. }
  91. }

博客更新至专栏【课程设计实验报告】:https://blog.csdn.net/weixin_43598687/category_11640051.html

相关文章