對樹結構認識:樹是由一個集合以及在該集合上定義的一種關係構成的,是一種重要的非線性數據結構。ios
困難:有些對樹操做中的遞歸算法理解有點困難,和各類非遞歸的遍歷方法。c++
樹結構能夠解決的問題:表達式的轉換,求樹的帶權路徑長度,並查集問題等等。git
2.1 題目1:6-1 jmu-ds-二叉樹操做集
2.2 設計思路(僞代碼或流程圖)
void CreateBTree(BTree &BT,string str)//層次創建二叉樹 { 定義樹形指針 t; queue<BTree> q; if(str[0]不爲'#'){ 創建根結點p; p->lchild和p->rchild分別爲空; 將p入隊 } else return; while(隊列非空){ q出隊,並將元素賦t; if(str[i]爲'#') t->lchild爲空; else{ 創建t的右結點t->lchild; 將t->lchild入隊; } i++; if(str[i]爲'#')t->rchild爲空; else{ 創建t的右結點t->rchild; 將r->lchild入隊;
}
}
BT=p; }2.3 代碼截圖
2.4 PTA提交列表說明
格式錯誤是我在頭個輸出前多了個空格算法
解決:用了題目給的全局變量
bool flag=true;經過他控制頭個空格的輸出。
數據結構
2.1 題目2:6-4 jmu-ds-表達式樹
2.2 設計思路(僞代碼或流程圖)
void InitExpTree(BTree &T,string str) { 創建字符型的棧 s1; 創建樹型的棧 s2;//s1存放字符,s2存放數字 int i=0; char c,f; BTree t;//根結點 BTree a,b;//子結點 if(str[0]爲'\0')return; while(str[i]不爲'\0'){ if(若‘/’後是否爲‘0’){ 輸出"divide 0 error!" T爲空; exit(0); } 創建樹結點t,並將str[i]賦給該結點 if(str[i]爲運算符){ if(棧s1爲空){ str[i]入棧 i++; continue; } 比較str[i],s1.top()的優先級,並賦給f; if((f=='>'||str[i]=='('||s1.top()=='(')&&str[i]!=')')s1.push(str[i]); else if(f=='<'||str[i]==')'){ while(!s1.empty()&&s1.top()!='('){ 將s1的棧頂元素給c並出棧 將s2的棧頂元素給b並出棧 將s2的棧頂元素給a並出棧 創建一個以c爲根結點,b和c爲子結點的樹 T=t; 將t入棧s2; } if(!s1.empty()&&s1.top()=='(')s1出棧; if(str[i]!=')')str[i]直接入棧到s1; } } else{ 將非運算符入棧到s2; } i++; } while(若棧s1和s2都不爲空){ 將s1的棧頂元素給c並出棧 將s2的棧頂元素給b並出棧 將s2的棧頂元素給a並出棧 創建一個以c爲根結點,b和c爲子結點的樹 T=t; 將t入棧s2; } } double EvaluateExTree(BTree T){ if(T==NULL)return 0; double a=T->data-'0'; if(若T->data不爲運算符)return a; if(T->data=='+')return EvaluateExTree(T->lchild)+EvaluateExTree(T->rchild); if(T->data=='-')return EvaluateExTree(T->lchild)-EvaluateExTree(T->rchild); if(T->data=='*')return EvaluateExTree(T->lchild)*EvaluateExTree(T->rchild); if(T->data=='/')return EvaluateExTree(T->lchild)/EvaluateExTree(T->rchild); }
2.3 代碼截圖
2.4 PTA提交列表說明
錯誤點:1.遇到除0,輸出
divide 0 error!,但我不知道如何直接退出
ide2.括號的優先級判斷錯誤,及遇到括號時的操做學習
解決:第一點,經過百度知道了exit(0),能夠直接退出程序編碼
第二點,我沒明白題目所給的括號的優先級的表示,所以我想只要遇到‘(’就入棧,遇到‘)’就將運算符出棧直到棧頂爲‘(’。 ps:不過看了同窗的代碼,才知道我這樣確實是麻煩了,我沒完美運用題目所給的條件。。。lua
2.1 題目3:7-1 還原二叉樹(25 分)
2.2 設計思路(僞代碼或流程圖)
BTree tree(char x[],char z[],int n)//用遞歸算法還原二叉樹 { if(若n爲0)返回空; int i=0; 創建樹結點t,並將先序x[0]給t->data; for(i=0;i<n;i++){ if(中序z[i]==先序的第一個元素x[0]){ 跳出循環; } } //以位置i爲分界進行左右還原 對t的左子樹進行還原t->left=tree(x+1,z,i); 對t的右子樹進行還原t->right=tree(x+i+1,z+i+1,n-i-1); return t; } int gethight(BTree t)//求二叉樹高 { int hl,hr,maxh; if(t不爲空){ 求左子樹hl的高度 求右子樹hr的高度 對比hl和hr,將高度大的賦給maxh return maxh+1; } else return 0; }
2.3 代碼截圖
2.4 PTA提交列表說明
#include<iostream> #include<cstdio> #include<cstring> using namespace std; #define N 10 // 帶編碼字符的個數,即樹中葉結點的最大個數 #define M (2*N-1) // 樹中總的結點數目 class HTNode{ // 樹中結點的結構 public: unsigned int weight; unsigned int parent,lchild,rchild; }; class HTCode{ public: char data; // 待編碼的字符 int weight; // 字符的權值 char code[N]; // 字符的編碼 }; void Init(HTCode hc[], int *n){ // 初始化,讀入待編碼字符的個數n,從鍵盤輸入n個字符和n個權值 int i; printf("input n = "); scanf("%d",&(*n)); printf("\ninput %d character\n",*n); fflush(stdin); for(i=1; i<=*n; ++i) scanf("%c",&hc[i].data); printf("\ninput %d weight\n",*n); for(i=1; i<=*n; ++i) scanf("%d",&(hc[i].weight) ); fflush(stdin); }// void Select(HTNode ht[], int k, int *s1, int *s2){ // ht[1...k]中選擇parent爲0,而且weight最小的兩個結點,其序號由指針變量s1,s2指示 int i; for(i=1; i<=k && ht[i].parent != 0; ++i){ ; ; } *s1 = i; for(i=1; i<=k; ++i){ if(ht[i].parent==0 && ht[i].weight<ht[*s1].weight) *s1 = i; } for(i=1; i<=k; ++i){ if(ht[i].parent==0 && i!=*s1) break; } *s2 = i; for(i=1; i<=k; ++i){ if(ht[i].parent==0 && i!=*s1 && ht[i].weight<ht[*s2].weight) *s2 = i; } } void HuffmanCoding(HTNode ht[],HTCode hc[],int n){ // 構造Huffman樹ht,並求出n個字符的編碼 char cd[N]; int i,j,m,c,f,s1,s2,start; m = 2*n-1; for(i=1; i<=m; ++i){ if(i <= n) ht[i].weight = hc[i].weight; else ht[i].parent = 0; ht[i].parent = ht[i].lchild = ht[i].rchild = 0; } for(i=n+1; i<=m; ++i){ Select(ht, i-1, &s1, &s2); 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; } cd[n-1] = '\0'; for(i=1; i<=n; ++i){ start = n-1; for(c=i,f=ht[i].parent; f; c=f,f=ht[f].parent){ if(ht[f].lchild == c) cd[--start] = '0'; else cd[--start] = '1'; } strcpy(hc[i].code, &cd[start]); } } int main() { int i,m,n,w[N+1]; HTNode ht[M+1]; HTCode hc[N+1]; Init(hc, &n); // 初始化 HuffmanCoding(ht,hc,n); // 構造Huffman樹,並造成字符的編碼 for(i=1; i<=n; ++i) printf("\n%c---%s",hc[i].data,hc[i].code); printf("\n"); return 0; }
代碼地址:https://blog.csdn.net/shuangde800/article/details/7341289spa
代碼功能:創建哈夫曼樹並轉碼
選擇緣由:代碼簡潔,學習到了哈夫曼樹的構建,初步瞭解了C++中public的用法