1. 程式人生 > >第四次作業 樹

第四次作業 樹

轉換 span for info main print tno 表達式 建二叉樹

1.2 樹結構學習體會

難,不是我等凡夫俗子可以學會的。

困難點:對遞歸的理解不夠透徹,一直轉不過來。

解決辦法:多看點代碼。

2.PTA實驗作業

題目一:6-4 jmu-ds-表達式樹(25 分)

題目:

  • 輸入一行中綴表達式,轉換一顆二叉表達式樹,並求解.
  • 表達式只包含+-*/運算符,操作數只有一位,且為整數(有興趣同學可以考慮負數小數,兩位數做法)。按照先括號,再乘除,後加減的規則構造二叉樹。
  • 如圖所示是"1+(2+3)*2-4/5"代數表達式對應二叉樹,用對應的二叉樹計算表達式的值。 轉換二叉樹如下:

思路:

建立表達式二叉樹

定義棧 s 用來存儲用運算的數字

定義字符棧 o p 用來存儲數字運算符號

首先 將’#‘ 如棧op

當str不為空的時候 進行while

if 是數字

就建立一個樹節點,將它賦值為str{i}的值,還要就左右孩子弄成NULL, 還要入棧

else 調動Precede

對它出現的運算符一一進行運作,

用swich

while op的top不是#

創建新的樹節點

賦予為op.top的值

在將棧裏的後面兩個值分別給左右孩子

/*計算表達式樹*/

利用遞歸把所有字符轉換成數字

while 若有樹節點

就計算

技術分享圖片

技術分享圖片

技術分享圖片

4.PTA提交列表說明

技術分享圖片

題目二:6-1 jmu-ds-二叉樹操作集(20 分)

本題要求用層次法創建二叉樹,層次法輸入序列是按樹的從上到下從左到右的順序形成,各層的空節點用字符 #表示

2.設計思路:

根據層次字符序列創建二叉樹

定義一個隊列q;

一個樹 temp

if str是#

就直接ruturn

else 建立一個樹節點

左右孩子為NULL;

將str【i】賦值給它

就節點入隊列

while !隊列

出隊列

分別判斷字符串後兩個是否為空

不是空:建立新節點,賦值

技術分享圖片

技術分享圖片

技術分享圖片

技術分享圖片

6-3 先序輸出葉結點(15 分)

本題要求按照先序遍歷的順序輸出給定二叉樹的葉結點。

2.設計思路:

if !BT 結束

當左右孩子多NULL時

就輸出節點

技術分享圖片

技術分享圖片

總分

185

也就是2分

技術分享圖片

4.閱讀代碼

  1. //huffmanCoding.c
  2. #include <stdio.h>
  3. #include <limits.h>
  4. #include <string.h>
  5. #include <stdlib.h>
  6. #define N 6
  7. typedef struct huffNode
  8. {
  9. unsigned int weight; //權重
  10. unsigned int lchild,rchild,parent; //左右子節點和父節點
  11. }HTNode,*HuffTree;
  12. typedef char **HuffCode;
  13. //找出數組中無父節點且權值最小的兩個節點下標,分別用s1和s2保存
  14. void select(const HuffTree &HT,int n,int &s1,int &s2);
  15. //HT:哈夫曼樹,HC:哈夫曼編碼,w:構造哈夫曼樹節點的權值,n:構造哈夫曼樹節點的個數
  16. void HuffmanCode(HuffTree &HT,HuffCode &HC,int *w,int n);
  17. int main()
  18. {
  19. int i;
  20. char key[N] = {‘0‘,‘A‘,‘B‘,‘C‘,‘D‘,‘E‘};//第0個元素保留不用
  21. int w[N] = {0,1,2,4,5,6}; //第0個元素保留不用
  22. HuffTree HT;
  23. HuffCode HC;
  24. HuffmanCode(HT,HC,w,N - 1);
  25. for ( i = 1; i < N; i++ )
  26. printf("%c:%s\n",key[i],HC[i]);
  27. printf("\n");
  28. return 0;
  29. }
  30. //找出數組中權值最小的兩個節點下標,分別用s1和s2保存
  31. void select(const HuffTree &HT,int n,int &s1,int &s2)
  32. {
  33. int i;
  34. s1 = s2 = 0;
  35. int min1 = INT_MAX;//最小值,INT_MAX在<limits.h>中定義的
  36. int min2 = INT_MAX;//次小值
  37. for ( i = 1; i <= n; ++i )
  38. {
  39. if ( HT[i].parent == 0 )
  40. {//篩選沒有父節點的最小和次小權值下標
  41. if ( HT[i].weight < min1 )
  42. {//如果比最小值小
  43. min2 = min1;
  44. s2 = s1;
  45. min1 = HT[i].weight;
  46. s1 = i;
  47. }
  48. else if ( (HT[i].weight >= min1) && (HT[i].weight < min2) )
  49. {//如果大於等於最小值,且小於次小值
  50. min2 = HT[i].weight;
  51. s2 = i;
  52. }
  53. else
  54. {//如果大於次小值,則什麽都不做
  55. ;
  56. }
  57. }
  58. }
  59. }
  60. //HT:哈夫曼樹,HC:哈夫曼編碼,w:構造哈夫曼樹節點的權值,n:構造哈夫曼樹節點的個數
  61. void HuffmanCode(HuffTree &HT,HuffCode &HC,int *w,int n)
  62. {
  63. int s1;
  64. int s2;
  65. int m = 2 * n - 1; //容易知道n個節點構造的哈夫曼樹是2n-1個節點
  66. int i,c,f,j;
  67. char *code; //暫存編碼的
  68. HT = (HuffTree)malloc((m+1)*sizeof(HTNode)); //0單元未使用
  69. for ( i = 1; i <= n; i++ )
  70. HT[i] = {w[i],0,0,0};//初始化前n個節點(構造哈夫曼樹的原始節點)
  71. for ( i = n + 1; i <= m; i++ )
  72. HT[i] = {0,0,0,0}; //初始化後n-1個節點
  73. //構建哈夫曼樹
  74. for ( i = n + 1; i <= m; i++)
  75. {
  76. select(HT,i-1,s1,s2);//找出前i-1個節點中權值最小的節點下標
  77. HT[s1].parent = i;
  78. HT[s2].parent = i;
  79. HT[i].lchild = s1;
  80. HT[i].rchild = s2;
  81. HT[i].weight = HT[s1].weight + HT[s2].weight;
  82. }
  83. //哈夫曼編碼
  84. HC = (char **)malloc((n)*sizeof(char *));
  85. //暫存編碼
  86. code = (char *)malloc(n*sizeof(char));//使用了第0單元
  87. for ( i = 1; i <= n; i++ )
  88. {
  89. for ( c = i, f = HT[c].parent, j = 0; f != 0; c = HT[c].parent, f = HT[c].parent, j++ )
  90. {//從葉子掃描到根
  91. if ( HT[f].lchild == c )
  92. {
  93. code[j] = ‘0‘;
  94. }
  95. else if(HT[f].rchild == c)
  96. {
  97. code[j] = ‘1‘;
  98. }
  99. else
  100. {//否則什麽也不做
  101. ;
  102. }
  103. }
  104. code[j] = ‘\0‘;
  105. HC[i] = (char *)malloc(strlen(code)*sizeof(char));
  106. strcpy(HC[i],code);
  107. }
  108. }

第四次作業 樹