第四次作業 樹
阿新 • • 發佈:2018-05-05
轉換 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.閱讀代碼
- //huffmanCoding.c
- #include <stdio.h>
- #include <limits.h>
- #include <string.h>
- #include <stdlib.h>
- #define N 6
- typedef struct huffNode
- {
- unsigned int weight; //權重
- unsigned int lchild,rchild,parent; //左右子節點和父節點
- }HTNode,*HuffTree;
- typedef char **HuffCode;
- //找出數組中無父節點且權值最小的兩個節點下標,分別用s1和s2保存
- void select(const HuffTree &HT,int n,int &s1,int &s2);
- //HT:哈夫曼樹,HC:哈夫曼編碼,w:構造哈夫曼樹節點的權值,n:構造哈夫曼樹節點的個數
- void HuffmanCode(HuffTree &HT,HuffCode &HC,int *w,int n);
- int main()
- {
- int i;
- char key[N] = {‘0‘,‘A‘,‘B‘,‘C‘,‘D‘,‘E‘};//第0個元素保留不用
- int w[N] = {0,1,2,4,5,6}; //第0個元素保留不用
- HuffTree HT;
- HuffCode HC;
- HuffmanCode(HT,HC,w,N - 1);
- for ( i = 1; i < N; i++ )
- printf("%c:%s\n",key[i],HC[i]);
- printf("\n");
- return 0;
- }
- //找出數組中權值最小的兩個節點下標,分別用s1和s2保存
- void select(const HuffTree &HT,int n,int &s1,int &s2)
- {
- int i;
- s1 = s2 = 0;
- int min1 = INT_MAX;//最小值,INT_MAX在<limits.h>中定義的
- int min2 = INT_MAX;//次小值
- for ( i = 1; i <= n; ++i )
- {
- if ( HT[i].parent == 0 )
- {//篩選沒有父節點的最小和次小權值下標
- if ( HT[i].weight < min1 )
- {//如果比最小值小
- min2 = min1;
- s2 = s1;
- min1 = HT[i].weight;
- s1 = i;
- }
- else if ( (HT[i].weight >= min1) && (HT[i].weight < min2) )
- {//如果大於等於最小值,且小於次小值
- min2 = HT[i].weight;
- s2 = i;
- }
- else
- {//如果大於次小值,則什麽都不做
- ;
- }
- }
- }
- }
- //HT:哈夫曼樹,HC:哈夫曼編碼,w:構造哈夫曼樹節點的權值,n:構造哈夫曼樹節點的個數
- void HuffmanCode(HuffTree &HT,HuffCode &HC,int *w,int n)
- {
- int s1;
- int s2;
- int m = 2 * n - 1; //容易知道n個節點構造的哈夫曼樹是2n-1個節點
- int i,c,f,j;
- char *code; //暫存編碼的
- HT = (HuffTree)malloc((m+1)*sizeof(HTNode)); //0單元未使用
- for ( i = 1; i <= n; i++ )
- HT[i] = {w[i],0,0,0};//初始化前n個節點(構造哈夫曼樹的原始節點)
- for ( i = n + 1; i <= m; i++ )
- HT[i] = {0,0,0,0}; //初始化後n-1個節點
- //構建哈夫曼樹
- for ( i = n + 1; i <= m; i++)
- {
- select(HT,i-1,s1,s2);//找出前i-1個節點中權值最小的節點下標
- HT[s1].parent = i;
- HT[s2].parent = i;
- HT[i].lchild = s1;
- HT[i].rchild = s2;
- HT[i].weight = HT[s1].weight + HT[s2].weight;
- }
- //哈夫曼編碼
- HC = (char **)malloc((n)*sizeof(char *));
- //暫存編碼
- code = (char *)malloc(n*sizeof(char));//使用了第0單元
- for ( i = 1; i <= n; i++ )
- {
- for ( c = i, f = HT[c].parent, j = 0; f != 0; c = HT[c].parent, f = HT[c].parent, j++ )
- {//從葉子掃描到根
- if ( HT[f].lchild == c )
- {
- code[j] = ‘0‘;
- }
- else if(HT[f].rchild == c)
- {
- code[j] = ‘1‘;
- }
- else
- {//否則什麽也不做
- ;
- }
- }
- code[j] = ‘\0‘;
- HC[i] = (char *)malloc(strlen(code)*sizeof(char));
- strcpy(HC[i],code);
- }
- }
第四次作業 樹