第五章題解
阿新 • • 發佈:2019-05-05
二叉鏈表 就是 一個 eno 方便 root color turn int
第五章 樹和二叉樹
本章我們重點學習了樹和二叉樹的定義、二叉樹的性質、存儲結構、二叉樹的先中後序遍歷。簡略的學習了樹和森林的存儲結構、遍歷,大致講解了哈夫曼樹的基本感念。在學習過程中,建樹和二叉樹的遍歷對我來講比較難。建樹可以用順序存儲也可以用二叉鏈表存儲,二叉樹的遍歷可以用遞歸實現也可以用非遞歸實現。下面主要講講我在PTA做題過程的一些感想和思路。
List Leaves
這道題的思路很簡單: 構造二叉樹的結點結構體、建立二叉樹、利用隊列輸出葉子結點
第一步 構造二叉樹的結點結構體
由於這道題的數據N只在10以內,所以我用了順序存儲結構。
1 typedef struct{ //定義二叉樹的結點結構2 int Left; 3 int Right; 4 }BiTreenode;
第二步 建立二叉樹
這裏要註意的問題有:
1.輸入的是char類型數據,因此為了標號方便要將其ASCII碼減去0的ASCII碼
2. 要定義一個數組root(bool類型或者int類型),以利於標記這個結點的子樹是否是根結點
int Buildtree(BiTreenode T[]){ bool root[10]={false}; int n,i; char x,y; cin>>n; for(i=0;i<n;i++){ cin>>x>>y; if(x!=‘-‘){//判斷左兒子是否為空,若不為空則左二子不為根結點,賦值為true T[i].Left=x-‘0‘; root[T[i].Left]=true; } else T[i].Left=-1; if(y!=‘-‘){ //判斷右兒子是否為空,若不為空則右兒子不為根結點,賦值為true T[i].Right=y-‘0‘; root[T[i].Right]=true; } else T[i].Right=-1; } for (int i=0; i<n; i++){//尋找根結點 ,當 root[]為-1時該式子成立,返回i的下標,即根節點的下標 if(!root[i]) return i; } }
第三步 利用隊列輸出葉子結點
利用隊列的好處是先進先出,而且在push一個數據之後就將它pop出來直接對它的左右孩子進行比較,非常方便
void OrderTree(BiTreenode T[],int x){//利用隊列輸出葉子結點 queue<int> q; int k; q.push(x);//將根節點入隊 while(!q.empty()){//當隊列不為空的時候,繼續執行循環 int tmp=q.front();//訪問隊列的首結點,也就是將最早入隊的結點的下標賦值給tmp if(T[tmp].Left!=-1) //若該節點的左兒子不為空,則將它壓入隊列中 q.push(T[tmp].Left); if(T[tmp].Right!=-1)//若該節點的右兒子不為空,則將它壓入隊列中 q.push(T[tmp].Right); q.pop(); //彈出隊列中的第一個元素 if(T[tmp].Left==-1 && T[tmp].Right==-1){ //若該結點的左兒子和右兒子均為空,則該結點為葉子結點,輸出該葉子結點 cout<<tmp; if(!q.empty()) //若隊列不為空,則輸出的不是最後一個葉子結點,在輸出空格 cout<<" "; } } }
樹的同構
這道題的思路主要是:構造結點結構體、構造二叉樹、將兩棵二叉樹進行比較。
第一步 構造結點結構體
這道題我也是用了順序存儲結構,與上一道題不一樣的地方是,這道題需要輸入字符域element。
typedef struct Treenode{ char element; int left; int right; }Treenode;
第二步 構造二叉樹
與上一道題目大同小異,主要是這裏需要構造兩棵樹。
第三步 將兩棵二叉樹進行比較
這個步驟有些復雜,主要是在比較過程中要把邏輯思路搞清楚。
1. 兩棵樹都是空樹的情況
2. 其中一棵樹是空樹的情況下
3. 根節點都存在但數值不同
4. 左子樹不存在,則遞歸判斷右子樹
5. 左子樹同時不空則無需交換左右子樹,否則交換左右子樹
bool Comparetree(int R1,int R2){ if( (R1==Null) && (R2==Null) ) return true;//兩棵樹都為空,則同構 if( ((R1==Null) && (R2!=Null)) || ((R1!=Null) && (R2==Null)) ) return false;//兩棵樹中有一棵為空,另外一棵樹不為空,則不同構 if( T1[R1].element!=T2[R2].element ) return false;//若兩棵樹都不為空,但樹根的值不相同,則不同構 if( (T1[R1].left==Null) && (T2[R2].left==Null) ) return Comparetree( T1[R1].right,T2[R2].right );//兩棵樹都不為空,根的值相同。若左子樹都為空,則是否同構取決於右邊,遞歸調用右子樹的判別 if( ((T1[R1].left!=Null) && (T2[R2].left!=Null)) && ((T1[T1[R1].left].element)==(T2[T2[R2].left].element)) ) return(Comparetree(T1[R1].left,T2[R2].left) && Comparetree(T1[R1].right,T2[R2].right));//左子樹是否同時不空,若同時不空則無需交換左右子樹 else return (Comparetree(T1[R1].left,T2[R2].right) && Comparetree(T1[R1].right,T2[R2].left)); };
目標總結:
完成了三分之二的題解,比上次進步一點。
下次目標:
完成所有題解。
第五章題解