此代码包含了构建哈夫曼树的代码,在后面几段

  1. //计算一个二叉树的节点个数,可以把所有的节点入队列,然后观察其rear的值,就知道其节点的个数,  这是一种广度的遍历方法
  2. //下面的是一中深度的遍历的方法  当节点为NULL时候,返回0,  当节点无子节点时,返回1 , 否则得话返回左右节点的总数
  3. int Nodes(BTNode *b)
  4. {
  5. int num1 = 0, num2 = 0;
  6. if(b == NULL)  return 0;
  7. else if(b->lchild == NULL && b->rchild == NULL) return 1;
  8. else
  9. {
  10. num1 = Nodes(b->lchild);       //此处记录的是其左子树的所有子节点的数目
  11. num2 = Nodes(b->rchild);      // 此处记录的是右子树所有节点的数目
  12. return (num1 + num2 + 1);     //此处 返回其左子树的数目+右子树的数目+ 本身的数目(也就是那个1)
  13. }
  14. }
  15. void LeafNodes(BTNode *b, int &leafnum)      //此函数记录叶子节点的数目, 与上面的函数类似,不过因为此函数不用计数 枝节点的数目, 所以没有num1 num2 等变量
  16. {                                            // 当其找到一个叶子节点的时候,就把叶子节点的计数器 ++,   因为leafnum是 &传参, 所以不用担心 回代的问题
  17. if(b == NULL) return ;
  18. else if(b->lchild == NULL && b->rchild  == NULL)  ++leafnum;
  19. else
  20. {
  21. LeafNodes(b->lchild,leafnum);
  22. LeafNodes(b->rchild,leafnum);
  23. }
  24. }
  25. int Nodes2(BTNode *b)              //此函数同样是求 树的叶子节点的数目
  26. {
  27. int num1 = 0, num2 = 0;
  28. if(b == NULL)  return 0;
  29. else if(b->lchild == NULL && b->rchild == NULL) {  return 1;}
  30. else
  31. {
  32. num1 = Nodes2(b->lchild);
  33. num2 = Nodes2(b->rchild);
  34. return (num1 + num2 );      //此处不同的是 没有 + 1, 产生的递增效果就是  枝节点 不会被递增上, 也就是说只有叶子节点才可以 对其产生作用。。。  此处加1 产生的作用是非常大的(因为递增的原因)
  35. }
  36. }
  37. void  DNodes(BTNode *b, int &dnum)       //此函数计算 有两个子节点的 节点的个数
  38. {
  39. if(b != NULL)            //当节点不为空的时候进行操作
  40. {
  41. if(b->lchild != NULL && b->rchild != NULL)     //此处表示 遇到了有双子节点的 节点
  42. ++dnum;
  43. DNodes(b->lchild,dnum);                       //遍历左子树
  44. DNodes(b->rchild,dnum);                      //遍历右子树
  45. }
  46. }
  47. int DNodes2(BTNode *b)                      //此函数是求树中 有双子节点的节点的个数
  48. {
  49. int num1 = 0, num2 = 0, n = 0;
  50. if(b == NULL) return 0;
  51. else if(b->lchild == NULL || b->rchild == NULL) n = 0;        //上面两个表明不符合条件 把 n置为 0
  52. else { n = 1; }
  53. num1 = DNodes2(b->lchild);
  54. num2 = DNodes2(b->rchild);
  55. return (num2 + num1 + n);                           //由题意知, n的值只能为 0 或 1
  56. }
  57. void  DNodes3(BTNode *b, int &dnum)         //此函数也是求 一个树中有多少个 双节点
  58. {
  59. int num1 = 0, num2 = 0;
  60. if(b != NULL)                          //当节点不为空的时候进行
  61. {
  62. if(b->rchild == NULL || b->lchild == NULL)   //当节点只有一个子节点的时候,进行递归操作
  63. {
  64. DNodes3(b->lchild, dnum);
  65. DNodes3(b->rchild, dnum);
  66. }else
  67. {
  68. ++dnum;                                  //当节点有两个子节点的时候, 把计数器++,  然后继续执行递归操作
  69. DNodes3(b->lchild, dnum);
  70. DNodes3(b->rchild, dnum);
  71. }
  72. }
  73. }
  74. void  DelTree(BTNode *b)  //此函数用来释放 树中节点的所占用的空间,  释放只能采用后序遍历,不能使用先序或者中序遍历,因为中有将子树的空间释放掉后才能释放根节点的空间
  75. {
  76. if(b !=  NULL)
  77. {   DelTree(b->lchild);
  78. DelTree(b->rchild);
  79. free(b);
  80. }
  81. }
  82. void Swap(BTNode *&b)         //交换左右子树  用到的还是 后序 递归
  83. {
  84. BTNode *temp;
  85. if(b != NULL)           //当节点存在的时候 进行操作
  86. {
  87. Swap(b->lchild);
  88. Swap(b->rchild);
  89. temp = b->lchild;           //交换左右子树
  90. b->lchild = b->rchild;
  91. b->rchild = temp;
  92. }
  93. }
  94. //对树的递归操作  莫过于先 遍历左子树, 在遍历右子树, 这是一个方面。 另一个方面是 先序 中序 还是后序
  95. void Swap1(BTNode *b, BTNode *&b1)             //此函数是由一个树,重新构建得到其另外一个左右子树交换的树。
  96. {
  97. if(b == NULL)
  98. {
  99. b1 = NULL;
  100. }
  101. else
  102. {
  103. b1 = (BTNode *)malloc(sizeof(BTNode));
  104. b1->data = b->data;
  105. Swap1(b->lchild, b1->rchild);
  106. Swap1(b->rchild, b1->lchild);
  107. }
  108. }
  109. void ancestor(BTNode *b,char r, char s)   //此函数是求得 值为 r s 节点的最近的祖先节点
  110. {                                       //不是一般性本例子采用后序遍历树, 并且假设 r 节点在 s 节点的左边
  111. BTNode *st[MAXSIZE],  *temp, *temp2; //本函数的思路是,后序遍历树 把遇到的节点进栈(这时候入栈中的元素都是r的祖先节点),当先(因为规定r节点在s节点的左边)遇到值为r节点的时候,就把栈的所有节点的值放入path数组,用以记录访问过的值
  112. int top = -1;                       //当遇到值为s的节点时候,就比较path数组与栈中的节点值,直到第一个不同即为其共同的祖先节点(当出栈的时候把 其不是公共的节点给出去了)
  113. bool  flag = true;
  114. char path[MAXSIZE];
  115. if(b != NULL)
  116. {
  117. temp = b;
  118. do      //此循环是后序遍历
  119. {
  120. while(temp != NULL)        //把左子树递归进栈
  121. {
  122. ++top;
  123. st[top] = temp;
  124. temp = temp->lchild;
  125. }
  126. flag = true;
  127. temp2 = NULL;
  128. while(flag && top > -1)
  129. {
  130. temp = st[top];
  131. if(temp->rchild == temp2)         //当节点的右节点访问过 或者 其右节点为空的时候,就访问它
  132. {
  133. if(temp->data == r)         //判断节点的值是否为r 如果是就给path数组赋值
  134. {
  135. for(int loop1=0; loop1 <= top; ++loop1)
  136. path[loop1] = st[loop1]->data;
  137. --top;                       //执行出栈操作
  138. temp2 = temp;               //表示已经访问过,,即对其做标记
  139. }else if(temp->data == s)
  140. {
  141. int loop2 = 0;
  142. while(st[loop2]->data == path[loop2])
  143. ++loop2;
  144. cout<<r<<" 与 "<<s<<" , 最近的共同祖先是 :"<<path[--loop2]<<endl;
  145. return ;
  146. }else
  147. {
  148. --top;
  149. temp2 = temp;
  150. }
  151. }else
  152. {
  153. flag = false;                 //此语句块表示当其右子节点没有被访问的时候,就跳出循环用flag做标志变量, 然后对其右子树执行递归操作
  154. temp = temp->rchild;
  155. }
  156. }
  157. }while(top > -1);
  158. }
  159. }
  160. char path1[MAXSIZE];
  161. int top = -1;
  162. void AncestorPath(BTNode *b, char s)     //此函数实现的是输出根节点到 值为 s 节点之间的路径,采用的递归操作
  163. {                                       //这是一种先序遍历
  164. if(b != NULL)
  165. {
  166. ++top;
  167. path1[top] = b->data;      //入栈
  168. if(b->data == s)           //判断是否满足条件
  169. {
  170. cout<<"路径为:"<<endl;
  171. for(int loop1 = 0; loop1 <= top; ++loop1)
  172. cout<<path1[loop1]<<' ';
  173. cout<<endl;
  174. return;
  175. }
  176. AncestorPath(b->lchild,s);
  177. AncestorPath(b->rchild,s);
  178. --top;                 //恢复环境
  179. }
  180. }
  181. //此上下两个函数 先序 与 后序的区别是 先序是先判断是否满足条件在进行 遍历左子树,  后序则是先深度遍历左子树,在判断右子树的时候,才判断是否满足条件
  182. //不管怎么说都 在栈中存在的元素都是所求的元素的  祖先节点
  183. void AncestorPath2(BTNode *b, char s)    //此函数同样是实现 根节点到值为s的节点之间路径输出,采用的方法是后序法,与求两个 节点 最近的祖先节点方法类似
  184. {
  185. BTNode *st[MAXSIZE], *temp, *temp2;
  186. int top = -1;
  187. bool flag = true;
  188. char path[MAXSIZE];
  189. if(b != NULL)
  190. {
  191. temp = b;
  192. do
  193. {
  194. while(temp != NULL)
  195. {
  196. ++top;
  197. st[top] = temp;
  198. temp = temp->lchild;
  199. }
  200. temp2 = NULL;
  201. flag = true;
  202. while(flag && top > -1)
  203. {
  204. temp = st[top];
  205. if(temp->rchild == temp2)
  206. {
  207. if(temp->data == s)
  208. {
  209. cout<<"根节点到 "<<s<<" 之间的路径为 :"<<endl;
  210. for(int loop1 = 0; loop1 <= top; ++loop1)
  211. cout<<st[loop1]->data<<' ';
  212. cout<<endl;
  213. return;
  214. }
  215. --top;
  216. temp2 = temp;
  217. }else
  218. {
  219. flag = false;
  220. temp = temp->rchild;
  221. }
  222. }
  223. }while(top > -1);
  224. }
  225. }
  226. char path3[MAXSIZE];
  227. int top2 = -1;
  228. void Link(BTNode *b)          //先序找树中的叶子节点
  229. {
  230. if(b != NULL)
  231. {
  232. if(b->lchild == NULL && b->rchild == NULL)
  233. path3[++top2] = b->data;
  234. else
  235. {
  236. Link(b->lchild);
  237. Link(b->rchild);
  238. }
  239. }
  240. }
  241. void Link2(BTNode *b)          //采用中序遍历 找叶子节点
  242. {
  243. if(b != NULL)
  244. {
  245. Link2(b->lchild);
  246. if(b->lchild == NULL && b->rchild == NULL)
  247. path3[++top2] = b->data;
  248. Link2(b->rchild);
  249. }
  250. }
  251. void Print(BTNode *b,int w)             //把树向 逆时针旋转90度打印出来
  252. {
  253. if(b != NULL)
  254. {
  255. Print(b->rchild, w+5);
  256. for(int loop1 = 0; loop1 <= w; ++loop1)
  257. cout<<' ';
  258. cout<<b->data<<endl;
  259. Print(b->lchild,w+5);
  260. }
  261. }
  262. float ExpValue(BTNode *b)      //此函数是计算一个树组成的表达式
  263. {
  264. if(b != NULL)              //当其不为0的时候执行操作
  265. {
  266. switch(b->data)
  267. {
  268. case '+' :
  269. return ExpValue(b->lchild) + ExpValue(b->rchild);  break;
  270. case '-' :
  271. return ExpValue(b->lchild) - ExpValue(b->rchild);  break;
  272. case '*' :
  273. return ExpValue(b->lchild) * ExpValue(b->rchild);  break;
  274. case '/' :
  275. return ExpValue(b->lchild) / ExpValue(b->rchild);  break;
  276. default :
  277. return b->data - '0';           //此处目前只能是各位数,如果节点的值是数的话,就直接返回
  278. }
  279. }
  280. }
  281. bool bflag = false;          //左子树的标记
  282. bool bflag2 = false;        //右子树的标记
  283. void  InorderExp(BTNode *b)       //此函数是通过树求得其表达式, 思路是当节点的数据域是符号的时候,就把其与左节点的数据域比较,如果左节点的数据域是符号并且
  284. {                               //子节点的优先级比根节点的小,那么就输出‘(’并把标记设置为true,      当遍历右子树的时候仍然拿其与右子树的数据域比较如果,其符号的优先级比右子树的优先级大,
  285. if(b != NULL)               //就输出一个‘(’然后设置标记为true
  286. {
  287. switch(b->data)
  288. {
  289. case '+' :
  290. case '-' :
  291. InorderExp(b->lchild);        //表示先遍历左子树
  292. cout<<b->data<<' ';         //输出其值
  293. InorderExp(b->rchild); break;  //遍历右子树
  294. case '*' :
  295. case '/' :               //当遇到 * /的时候就应当判断优先级了
  296. if(b->lchild != NULL)       //此处是判断左子树
  297. {
  298. if(b->lchild->data == '+' || b->lchild->data == '-')
  299. {   cout<<'(';
  300. bflag = true;
  301. }
  302. }
  303. InorderExp(b->lchild);
  304. if(bflag)
  305. { cout<<')';  bflag = false;}
  306. cout<<b->data<<' ';         //此处才是输出 * 或者/ 的地方,也就是在 ‘(’‘)’都输出完成的时候,如果有的话
  307. if(b->rchild != NULL)       //此处判断右子树
  308. {
  309. if(b->rchild->data == '+' || b->rchild->data == '-')
  310. {   cout<<'(';
  311. bflag2 = true;
  312. }
  313. }
  314. InorderExp(b->rchild);
  315. if(bflag2)
  316. { cout<<')'; bflag2 = false; }
  317. break;
  318. default :
  319. cout<<b->data<<' ';
  320. break;
  321. }
  322. }
  323. }
  324. int process(char op1, char op2) //此函数是判断优先级
  325. {
  326. if(op1 != '+' && op1 != '-' && op1 != '*' && op1 != '/')  return -1;
  327. if(op2 != '+' && op2 != '-' && op2 != '*' && op2 != '/')  return -1;
  328. if(op1 == '+' || op1 == '-')
  329. {
  330. return 0;
  331. }
  332. if(op1 == '*' || op1 == '/')
  333. {
  334. if(op2 == '+' || op2 == '-')
  335. return 1;
  336. }
  337. }
  338. void InorderExp2(BTNode *b)    //此函数也是求得表达式
  339. {
  340. int flag1 = 2;
  341. int flag2 = 2;
  342. if(b != NULL)
  343. {
  344. if(b->lchild != NULL)
  345. {
  346. flag = process(b->data,b->lchild->data);
  347. if(flag == 1) cout<<'(';
  348. InorderExp(b->lchild);
  349. if(flag == 1) cout<<')';
  350. }
  351. cout<<b->data;
  352. if(b->rchild != NULL)
  353. {
  354. flag2 = process(b->data,b->rchild->data);
  355. if(flag2 == 1) cout<<'(';
  356. InorderExp(b->rchild);
  357. if(flag2 == 1) cout<<')';
  358. }
  359. }
  360. }
  361. float value[MAXSIZE];
  362. int top22 = -1;
  363. char postExp[MAXSIZE];
  364. void PostExp(BTNode *b)   //此函数的目的是把树转换为后缀表达式,怎么转换为后缀表达式呢??? 采用后序遍历即可
  365. {                       //因为符号位总是位于双亲结点,这样就能先把 数字位给进栈, 然后进栈符号位
  366. if(b != NULL)
  367. {
  368. PostExp(b->lchild);
  369. PostExp(b->rchild);
  370. ++top22;
  371. postExp[top22] = b->data;
  372. }
  373. }
  374. void CompValue(char postExp[]) //此函数是为了通过后缀表达式来求得其值
  375. {   top = -1;
  376. char ch;
  377. int loop1 = 0;
  378. ch = postExp[loop1];
  379. float lValue = 0.0f, rValue = 0.0f, fValue = 0.0f;
  380. while(ch != '\0')
  381. {
  382. switch(ch)
  383. {
  384. case '+' :
  385. rValue = value[top];
  386. --top;
  387. lValue = value[top];
  388. fValue = lValue + rValue;
  389. value[top] = fValue;
  390. ch = postExp[++loop1];
  391. break;
  392. case '-' :
  393. rValue = value[top];
  394. --top;
  395. lValue = value[top];
  396. fValue = lValue - rValue;
  397. value[top] = fValue;
  398. ch = postExp[++loop1];
  399. break;
  400. case '*' :
  401. rValue = value[top];
  402. --top;
  403. lValue = value[top];
  404. fValue = lValue * rValue;
  405. value[top] = fValue;
  406. ch = postExp[++loop1];
  407. break;
  408. case '/' :
  409. rValue = value[top];
  410. --top;
  411. lValue = value[top];
  412. if(rValue == 0)  { cout<<"发生除零错误。"<<endl; exit(1); }
  413. fValue = lValue / rValue;
  414. value[top] = fValue;
  415. ch = postExp[++loop1];
  416. break;
  417. default :
  418. fValue = float( ch - '0');     //因为数字位 是个位数,所以此处没有进行处理
  419. ++top;
  420. value[top] = fValue;
  421. ch = postExp[++loop1];
  422. break;
  423. }
  424. }
  425. if(top == 0)
  426. { cout<<"所求的值为:"<<value[top]<<endl; }
  427. else
  428. { cout<<"求值错误。"<<endl; }
  429. }
  430. void NodeToRoot(BTNode *b)    //此函数是在结点中增加一个双亲域以后, 输出每个结点到根节点的路径
  431. {                           //采用先序遍历
  432. BTNode *temp;
  433. if(b != NULL)
  434. {
  435. temp = b;
  436. while(temp != NULL)
  437. {
  438. cout<<temp->data<<' ';
  439. temp = temp->parent;
  440. }
  441. cout<<endl;
  442. NodeToRoot(b->lchild);
  443. NodeToRoot(b->rchild);
  444. }
  445. }
  446. void PreToPost(ElemType pre[], int begin1, int end1, ElemType post[], int begin2, int end2)
  447. {                               //此函数将先序序列转换为后序序列, 因为先序序列的第一个元素是后序序列的最后一个元素,  然后就以此为条件进行递归操作
  448. int half = 0;
  449. if(end1 >= begin1)
  450. {   half = (end1 - begin1 ) / 2;       //half保存了中间的值
  451. post[end2] = pre[begin1];
  452. PreToPost(pre, begin1 + 1, begin1 + half, post, begin2,begin2 + half -1); //此处是遍历先序左子树, 要注意的是在使用half的时候,应该加上开始点,  其half是一个区间,不是一个点,加上begin开始点后,才表示中间点的位置
  453. PreToPost(pre, begin1 + half + 1, end1, post,begin2 + half, end2 -1);     //此处是遍历先序右子树
  454. }
  455. }
  456. void CreateHT(HTNode ht[], int n)    //通过数组构造一棵哈夫曼树, 因为一棵哈夫曼树有n个节点的话,就会有总共2n - 1 个节点
  457. {
  458. int loop1 = 0, loop2 = 0, loop3 = 0, lpos = 0, rpos = 0;
  459. float weight1 = 0.0f, weight2 = 0.0f;      //用来保存权值,其中weight1 保存的是较小的
  460. for(loop1 =0; loop1 < n; ++loop1)    //此循环把双亲 左右孩子节点域置为 -1;
  461. {   ht[loop1].parent = -1;
  462. ht[loop1].lchild = -1;
  463. ht[loop1].rchild = -1;
  464. }
  465. for(loop1 = n; loop1 < 2 * n + 1; ++loop1)     //由于数组前面的n个节点是叶子节点,所以此处处理 后面的 n -1 个非叶子节点
  466. {
  467. weight1 = 32767.0f;
  468. weight2 = 32767.0f;
  469. for(loop2 = 0; loop2 < loop1; ++loop2 )
  470. {
  471. if(ht[loop2].parent == -1)         //只处理没有双亲节点的 节点
  472. {
  473. if(ht[loop2].weight < weight1)      //保存最小的和 第二最小的权值及其位置
  474. {
  475. weight2 = weight1;     rpos = lpos;
  476. weight1 = ht[loop2].weight;  lpos = loop2;
  477. }
  478. else if(ht[loop2].weight < weight2)
  479. {
  480. weight2 = ht[loop2].weight;
  481. rpos = loop2;
  482. }
  483. }
  484. }
  485. ht[loop1].lchild = lpos;    ht[loop1].rchild = rpos;  ht[loop1].weight = ht[lpos].weight + ht[rpos].weight;
  486. ht[lpos].parent = loop1;    ht[rpos].parent = loop1;
  487. }
  488. }
  489. //哈夫曼编码只能是叶子节点,并且哈夫曼树中只有度为 0 或2 的节点
  490. typedef struct
  491. {
  492. char cd[MAXSIZE]; //存储根节点到叶子节点的编码,即 0 或 1
  493. int start;        //开始位置
  494. }HCode;   //存储哈夫曼遍历的 节点结构
  495. /*
  496. void CreateHCode(HTNode ht[], HCode hcd[], int n)    //此函数是根据哈夫曼树构造哈夫曼编码,思路是从每个叶子节点开始遍历到根节点, 如果节点是左节点 则表示为0 ,如果右节点否则表示为1
  497. {
  498. int loop1 = 0, parent;
  499. HCode hc;
  500. for(loop1 = 0; loop1 < n; ++loop1)     //ht数组的前面n个元素是叶子节点, 所以遍历前面n个节点
  501. {
  502. hc.start = n;
  503. parent = ht[loop1].parent;
  504. while(parent != -1)             //直到根节点 构造哈夫曼遍历
  505. {
  506. if(ht[parent].lchild == ht[loop1])      //如果是左节点的话,为 0
  507. hc.cd[hc.start--] = '0';
  508. else
  509. hc.cd[hc.start--] = '1';           //否则为右节点,那么就为 1
  510. parent = ht[parent].parent;         //
  511. }
  512. ++hc.start;
  513. hcd[loop1] = hc;
  514. }
  515. }
  516. */
  517. typedef char ElemType;
  518. typedef struct hnode
  519. {
  520. int weight;
  521. ElemType data;
  522. struct hnode *lchild, *rchild;
  523. }HTree;
  524. typedef struct
  525. {
  526. ElemType data;
  527. int weight;
  528. }Node;
  529. typedef struct
  530. {
  531. char code[10];
  532. int weight;
  533. ElemType data;
  534. }NodeCode;
  535. struct cmp1
  536. {
  537. bool operator() (HTree *node1, HTree *node2)
  538. {
  539. return node1->weight >= node2->weight;
  540. }
  541. };
  542. void CreateHuffm(HTree *&root, Node nodes[], int num) //此函数借助priority_queue<> 构造哈夫曼树
  543. {
  544. int loop1 = 0, weight = 0;
  545. HTree *temp = NULL,*lchild = NULL, *rchild = NULL;
  546. priority_queue<HTree *, vector<HTree *>, cmp1>  qp;
  547. for(loop1 = 0; loop1 < num; ++loop1)
  548. {
  549. temp = (HTree *)malloc(sizeof(HTree));
  550. temp->lchild = temp->rchild = NULL;
  551. temp->data = nodes[loop1].data;
  552. temp->weight = nodes[loop1].weight;
  553. qp.push(temp);
  554. }
  555. while(qp.size() != 1)
  556. {
  557. lchild = qp.top();
  558. qp.pop();
  559. rchild = qp.top();
  560. qp.pop();
  561. temp = (HTree *)malloc(sizeof(HTree));
  562. temp->lchild = lchild;
  563. temp->rchild = rchild;
  564. temp->weight = lchild->weight + rchild->weight;
  565. qp.push(temp);
  566. }
  567. root = qp.top();
  568. qp.pop();
  569. }
  570. void disp(HTree *tree)
  571. {
  572. if(tree != NULL)
  573. {
  574. cout<<tree->weight<<endl;
  575. disp(tree->lchild);
  576. disp(tree->rchild);
  577. }
  578. }
  579. NodeCode code[MAXSIZE];
  580. int loop = 0, looop = 0;
  581. char pathx[10];
  582. void HuffmCode(HTree *tree)      //此函数求得每个节点的哈弗曼编码, 利用先序递归的方式
  583. {
  584. if(tree != NULL)
  585. {
  586. if(tree->lchild == NULL && tree->rchild == NULL)
  587. {
  588. code[looop].data = tree->data;
  589. code[looop].weight = tree->weight;
  590. strcpy(code[looop].code, pathx);            //此步骤没用到loop的值,所以下面
  591. ++looop;
  592. }
  593. if(tree->lchild != NULL)
  594. {
  595. pathx[loop] = '0';
  596. ++loop;
  597. pathx[loop] = '\0';                 //                                     应该加上'\0'
  598. HuffmCode(tree->lchild);
  599. }
  600. if(tree->rchild != NULL)
  601. {
  602. pathx[loop] = '1';
  603. ++loop;
  604. pathx[loop] = '\0';
  605. HuffmCode(tree->rchild);
  606. }
  607. --loop;
  608. pathx[loop] = '\0';
  609. }
  610. }

转载于:https://blog.51cto.com/saibro/1183621

树的更多相关算法-3相关推荐

  1. Algorithm:树相关算法(BBT/BST/B树/R树)简介(二叉查找树、二叉查找树的插入节点、二叉查找树的删除、二叉树的遍历、平衡二叉树)C 语言实现

    Algorithm:树相关算法(BBT/BST/B树/R树)简介(二叉查找树.二叉查找树的插入节点.二叉查找树的删除.二叉树的遍历.平衡二叉树)C++语言实现 目录 树的基础知识 1.二叉树的遍-前序 ...

  2. 不再惧怕!二叉树结构相关算法总结 | 原力计划

    作者 | BoCong-Deng 来源 | CSDN 博客,责编 | 夕颜 出品 | CSDN(ID:CSDNnews) 写在前面 树结构对于程序员来说应该不陌生,特别是二叉树,基本只要接触算法这一类 ...

  3. JavaSE - 数组的相关算法

    JavaSE - 数组的相关算法 本节学习目标: 了解并掌握Java中随机数的生成方式: 了解常用的数组赋值算法: 了解并掌握浅拷贝与深拷贝的区别与理解 了解并掌握常用的数组查找算法: 了解并掌握常用 ...

  4. jvm学习第十、十一天、十二天—垃圾回收器1、垃圾回收的相关概述2、 垃圾回收相关算法3、 垃圾回收器

    标题:jvm学习第十.十一天.十二天-垃圾回收器 学习内容: 1.垃圾回收的相关概述 2. 垃圾回收相关算法 3. 垃圾回收器 内容详情: 1.垃圾回收的相关概述 什么是垃圾( Garbage)? 垃 ...

  5. 不再惧怕!二叉树结构相关算法总结

    写在前面 树结构对于程序员来说应该不陌生,特别是二叉树,基本只要接触算法这一类的都一定会碰到的,所以我打算通过一篇文章,对二叉树结构的相关算法进行总结汇总,思路和代码实现相结合,让你不在惧怕二叉树.( ...

  6. 从K近邻算法、距离度量谈到KD树、SIFT+BBF算法

    原文出自:http://blog.csdn.net/v_JULY_v/article/details/8203674 前言 前两日,在微博上说:"到今天为止,我至少亏欠了3篇文章待写:1.K ...

  7. 【转】从K近邻算法、距离度量谈到KD树、SIFT+BBF算法

    最近在看<统计学习方法>,发现这么一篇好文章,与大家分享 转自:http://blog.csdn.net/v_july_v/article/details/8203674?reload 前 ...

  8. 一文详解缺陷检测相关算法!

    缺陷检测是什么? 缺陷检测,是各行业产品质量管理体系中的重要一环,也是产品在正式投入市场应用前最后一道屏障.由于产品可能出现的品质问题多种多样,没有统一的衡量标准,所以一直以来,产品质检都是依靠人工来 ...

  9. 在决策树类相关算法中,一个接点的基尼系数通常是大于还是小于他的父节点?是总是大于还是总是小于?

    在决策树类相关算法中,一个接点的基尼系数通常是大于还是小于他的父节点?是总是大于还是总是小于? 下图为笔者构建的树模型并可视化之后的效果图: 可视化决策树的代码如下: 具体细节可以参考: 构建决策树模 ...

最新文章

  1. php kint调试,PHP调试助手
  2. python——模块1、模块的分类
  3. BZOJ2741 【FOTILE模拟赛】L 【可持久化trie + 分块】
  4. new出来的对象怎么回收_JVM的内存模型及垃圾回收算法
  5. CentOS 服务器搭建 mediawiki
  6. Android Binder Debug
  7. win11微软拼音输入法失效、没有候选框、不显示语言栏的问题
  8. 存在感应雷达模块,LED灯感应控制,微波雷达技术应用
  9. python窗口显示表格_python表格界面
  10. mysql字符串索引与数字索引_×××数字和字符串数字的索引使用情况
  11. html 给div设置边框颜色代码,div边框颜色设置
  12. 3812 机器人走迷宫(枚举 + 全排列)
  13. 各种字符编码与Char字符
  14. ShareIntentUtil【调用系统自带的分享的工具类】
  15. 【故障诊断】基于最小熵反卷积、最大相关峰度反卷积和最大二阶环平稳盲反卷积等盲反卷积方法在机械故障诊断中的应用研究(Matlab代码实现)
  16. excel服务器okr系统,OKR工具能帮企业落地OKR吗?从飞书OKR看专业工具的价值
  17. 一年的第多少周+一个月的第多少天+一周的第多少天
  18. 大学生python期末解答题_大学mooc2020年用Python玩转数据期末考试大全答案
  19. 用canvas画转动的阴阳鱼
  20. RANSAC及图像拼接上的应用

热门文章

  1. FreeRTOS 事件标志组 ——提高篇
  2. 修正memcache.php中的错误示例
  3. Java 添加播放MIDI音乐
  4. NLP之CRF分词训练(六)
  5. 微软修复Windows 10周年更新KB3194496累积更新安装问题
  6. 从视觉检测窥探人类大脑和数字大脑的差别
  7. Android Touch事件传递机制 二:单纯的(伪生命周期)
  8. oracle em命令行配置及界面按钮乱码问题解决方法
  9. C# WInForm中 窗体的this.width和this.height的属性值不能大于显示器的最大分辨率
  10. Exchange server 2013 安装部署初体验