本科课程【数据结构与算法】实验4—— 构造哈夫曼树、深度优先搜索

x33g5p2x  于2022-03-18 转载在 其他  
字(3.8k)|赞(0)|评价(0)|浏览(445)

大家好,我是【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. 实现图的深度优先搜索

二、 实验内容

1. 实验任务

(1)构造赫夫曼树
(2)深度遍历无向图

2. 程序设计

1) 数据输入(输入哪些数据、个数、类型、来源、输入方式)

输入叶子的数量num(int整型);
各叶子节点的权值weight(int 整型)

输入节点(char字符型)
输入边及边的权值(int 整型)

2) 数据存储(输入数据在内存中的存储)

采用new方法动态分配内存;
每一个二叉树储存在HuffmanTree[i]中;

采用邻接矩阵存储,一维数组存储节点,二维数组存储边

3) 数据处理(说明处理步骤。若不是非常简单,需要绘制流程图)

①初始化HT[1-2n-1] ; left=right=0 ; parent=0;

②输入n个叶子节点的权值weight;

③进行n-1次合并,每次选择权值最小的两个合并产生一个树HT[new],
HT[s1].parent=i ; HT[s2].parent=i ;
HT[new].weight=HT[s1].weight + HT[s2].weight;
HT[new].left=s1 , HT[new].right=s2;
经过n-1次合并后剩下最后一个二叉树即为哈夫曼树
————————————————————————————————————————
① 从始节点v开始,访问他的任一邻接节点w1,再w2出发访问与w2邻接但未被访问的节点w3,直至所有节点被访问
② 接着,退回一步到刚访问的节点看是否有未被访问的其他结点
③ 如果有,继续访问;如果没有,就再退回一步搜索。重复上述过程,直至连通图中所有节点都被访问为止

三、 实验环境

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

源代码(C++实现)

构造哈夫曼树

  1. #include<iostream>
  2. using namespace std;
  3. typedef struct
  4. {
  5. int weight; //权值
  6. int parent;
  7. int left, right;
  8. }HtNode,*HuffmanTree;
  9. void InitTree(HuffmanTree HT, int n);
  10. void CreatHuffmanTree(HuffmanTree HT, int n);
  11. void Select(HuffmanTree HT,int,int &,int &);
  12. int main()
  13. {
  14. int num; //叶子数
  15. cout << "请输入哈夫曼树的叶子数:";
  16. cin >> num;
  17. HuffmanTree Htree = NULL;
  18. InitTree(Htree, num);
  19. CreatHuffmanTree(Htree, num);
  20. delete[] Htree;
  21. system("pause");
  22. return 0;
  23. }
  24. void InitTree(HuffmanTree HT,int n) //初始化哈夫曼树
  25. {
  26. if (n <= 1)
  27. return;
  28. int HuffmanLength = 2 * n - 1;
  29. HT = new HtNode[HuffmanLength + 1];
  30. for (int i = 1; i <= HuffmanLength; i++)
  31. {
  32. HT[i].left = 0;
  33. HT[i].right = 0;
  34. HT[i].parent = 0;
  35. }
  36. cout << "输入各叶子的权值分别为:";
  37. for (int i = 1; i <= n; i++)
  38. {
  39. cin >> HT[i].weight;
  40. }
  41. }
  42. void CreatHuffmanTree(HuffmanTree HT,int n)
  43. {
  44. int HuffmanLength = 2 * n - 1;
  45. int s1, s2;
  46. for (int i = n + 1; i <= HuffmanLength; i++)
  47. {
  48. Select(HT,n,s1,s2);
  49. HT[s1].parent = i;
  50. HT[s2].parent = i;
  51. HT[i].left = s1;
  52. HT[i].right = s2;
  53. HT[i].weight = HT[s1].weight + HT[s2].weight;
  54. }
  55. }
  56. void Select(HuffmanTree HT,int n,int &s1,int &s2) //选择权值最小的两个节点
  57. {
  58. int i, j;
  59. for (i = 1; i <= n; i++)
  60. {
  61. if (HT[i].parent == 0)
  62. {
  63. s1 = i;
  64. break;
  65. }
  66. }
  67. for (j = i + 1; j <= n; j++)
  68. {
  69. if (HT[j].parent == 0)
  70. {
  71. s2 = j;
  72. break;
  73. }
  74. }
  75. for (i = 1; i <= n; i++)
  76. {
  77. if ((HT[s1].weight>HT[i].weight) && (HT[i].parent == 0) && (s2 != i))
  78. s1 = i;
  79. }
  80. for (j = i+1; j <= n; j++)
  81. {
  82. if ((HT[s2].weight>HT[j].weight) && (HT[j].parent == 0) && (s1 != i))
  83. s2 = i;
  84. }
  85. }

深度优先搜索

  1. #include<iostream>
  2. #include <stdio.h>
  3. using namespace std;
  4. #define MAX_VERTEX_NUM 50 // 顶点最大数量
  5. #define MAXINT 32466; //无穷大数
  6. bool visit[MAX_VERTEX_NUM];
  7. typedef struct
  8. {
  9. char vexs[MAX_VERTEX_NUM]; //顶点表
  10. int arcs[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
  11. int vexnum, arcnum;
  12. }AMGraph;
  13. //创建图
  14. void Create(AMGraph &G);
  15. //查找节点
  16. int Find(AMGraph G, int v);
  17. //深度优先遍历
  18. void DFS(AMGraph G, int u);
  19. //初始化图节点
  20. void Init(AMGraph G);
  21. int main()
  22. {
  23. AMGraph graph;
  24. Create(graph);
  25. Init(graph);
  26. int first;
  27. cout << "从几号节点开始遍历:";
  28. cin >> first;
  29. cout << "广度优先遍历为:" << endl;
  30. DFS(graph, first);
  31. system("pause");
  32. return 0;
  33. }
  34. /*
  35. 用于创建一个无向图
  36. */
  37. void Create(AMGraph &G)
  38. {
  39. int i,j,k,w;
  40. char v1, v2;
  41. cout << "输入图的顶点数和边数:";
  42. cin >> G.vexnum >> G.arcnum; //顶点数和边数
  43. for (i = 0; i < G.vexnum; i++)
  44. {
  45. for (j = 0; j < G.arcnum; j++)
  46. {
  47. G.arcs[i][j] = 0;
  48. }
  49. }
  50. cout << "输入边关系和边的权值:" << endl;
  51. for (k = 0; k < G.arcnum; k++)
  52. {
  53. cin >> v1 >> v2 >> w;
  54. i = Find(G, v1);
  55. j = Find(G, v2);
  56. G.arcs[i][j] = w;
  57. G.arcs[j][i] = G.arcs[i][j];
  58. }
  59. }
  60. /*
  61. 用于初始化图的节点
  62. */
  63. void Init(AMGraph G)
  64. {
  65. cout << "输入各节点名称:"<<endl;
  66. for (int i = 0; i < G.vexnum; i++)
  67. {
  68. cin >> G.vexs[i];
  69. }
  70. for (int i = 0; i < MAX_VERTEX_NUM; i++)
  71. visit[i] = false;
  72. }
  73. /*
  74. 用于查找节点
  75. */
  76. int Find(AMGraph G, int v)
  77. {
  78. int i;
  79. for (i = 0; i < G.vexnum; i++)
  80. {
  81. if (v == G.vexs[i])
  82. return i;
  83. return -1;
  84. }
  85. }
  86. /*
  87. 深度优先遍历
  88. */
  89. void DFS(AMGraph G, int u)
  90. {
  91. cout << u;
  92. visit[u] = true;
  93. for (int i = 0; i < G.vexnum; i++)
  94. {
  95. if ((G.arcs[u][i] != 0) && (visit[i] == false))
  96. DFS(G, i);
  97. }
  98. }

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

相关文章