王道資料結構課後題 P121

2021-07-16 12:54:16 字數 3933 閱讀 5495

7、判斷乙個二叉樹是否為完全 二叉樹。

一開始是想著利用遞迴,判斷有左孩子而無右孩子的節點的個數,並且要求左孩子為葉子節點。

判斷的條件很複雜,最後發現這種方法實際上是有問題的。

如果同時碰到兩個節點同時為有左葉子節點而右子樹為空,這種情況按照判斷應當返回false

但是這種方法並不能正確返回

1 / \

2 3

/ /

4 5

正確的方法應當是利用層次遍

不同於一般的層次遍歷的地方在於無論node->left ,right 是否為空全部推入。

如果碰到第乙個為空的node,設定flag=1;在以後如果遇到任意乙個不為空的節點,必然是false的

道理也比較清晰明了

class solution

}return

true;

}//遇到多個 有左孩子而無右孩子 的情況將無能為力

//正確的方法應當是使用佇列,如果出現了空節點,那麼之後出現的節點不再可能!=null

//利用flag表示父親節點是否是有lchild而無rchild

// //flag>1,要求這個節點不能再有葉子節點,否則必錯

// return isfull(root,0)==0;

// int isfull(treenode* root,int flag)

};

8、判斷孩子節點數量為2【度為2】的節點數

自頂向下遞迴即可解決~

class solution

};

10、求先序遍歷中第k個節點的值

使用棧的話很容易解決。

如果用遞迴的話,也值需要外設乙個變數。然後利用先序遍歷的思想,在相應的位置對這個變數進行操作就好了。

class

solution

// else if(k<1) return 0;

// else k--;

//

// return get_kth(root->left,k)+get_kth(root->right,k);

//

// 非遞迴版

// stackq;

// q.push(root);

// int count=0,num=root->val;

// while(!q.empty())

// return -1;

}//先定義後實現

// void get_kth(treenode* root);

//直接在class內部實現

void get_kth(treenode* root)

get_kth(root->left);

get_kth(root->right);

}};//void solution::get_kth(treenode* root)

//

// get_kth(root->left);

// get_kth(root->right);

//}

12、求x的祖先節點

思路是使用乙個棧,從根節點開始遞迴,存放遞迴到當前步驟時候有哪些節點。

並使用乙個陣列(引用傳遞)當找到x的時候,取出當前棧內所有元素,返回。

class solution

void getx(treenode* root,int x,vector

&result,vector

& cur)

getx(root->left,x,result,cur);

getx(root->right,x,result,cur);

//遞迴推出

result.pop_back();

}};

13、尋找兩個節點的公共祖先

一開始我所想是自底向上,傳乙個bool值,判斷有無找到和所需要值相對應的節點。

如果left==true && right==true 說明是root,另一種情況是left||right 並且root是所需要找尋的節點。

其實我所採取的做法的分情況討論是沒有必要的。

如果找到乙個節點root,就應當返回。這樣再判斷左右節點,如果兩節點分布在兩棵子樹上,則返回root。

而之前所擔心的,乙個節點是另乙個節點的祖先

這種方式會直接將這個節點一直返回到root節點而無法遍歷到另一節點。

但是,這個節點就是祖先節點

1 /

2 /

3 例如一路左子樹往下,任取兩個節點,先遍歷到的那個節點就是祖先。

class solution

bool getancestor(treenode* root,int x,int y,treenode*

&target)

//如果孩子節點僅有乙個是true,但是當前節點是目的節點

//故二者公共祖先為當前節點

if((left || right)&&(root->val == x || root->val==y))

//當前節點是需要找尋的節點

if(root->val==x || root->val==y)

return

true;

//返回兩個子節點的或

return left || right;

}};

13plus、如果我們把二叉樹看成乙個圖,父子節點之間的連線看成是雙向的,我們姑且定義」距離」為兩節點之間邊的個數。寫乙個程式求一棵二叉樹中相距最遠的兩個節點之間的距離。

實際上可以歸結於求左右子樹和的最大值的問題。

int max=int_min;

int getmaxdepth(treenode* root)

15、對於乙個滿二叉樹,將前序轉化為後序。

滿二叉樹的左右子樹數量相等。

故可在拿走乙個節點之後,確定剩下的一半是左子樹的節點,一半是右子樹的。

對於乙個順序排列的abcdefg滿二叉樹

abdecfg

debfgca

post[end]=pre[start],接著將剩下的節點進行二分。

half=(start-end)/2;

分別對兩部分遞迴求取。

注意在這時候,不能算上s1和e1所佔的位置,所以位置要適當微調。

class solution

}};

17、判斷兩棵二叉樹是相似的

這題其實就是判斷兩棵二叉樹具有相同的樹形結構

可以使用遞迴完成

if(!root1 &&

!root2) return

true;

if(!root1 ||

!root2) return

false;

//要求左右子樹均相似

return issimilar(root1->left,root2->left) && issimilar(root1->right,root2->right);

19、求帶權路徑長度之和

每個節點的帶權路徑長度 =節點值*節點深度

難度倒還好,傳入乙個deep深度隨著遞迴增加即可

注意可以不必採取先加後減deep的操作,而是可以在傳值的時候直接加1即可

int getwpl(treenode* root)

int wpl(treenode* root,int deep)

王道資料結構課後習題 P018

3.長度為l的順序表,編寫乙個時間複雜度為o n 空間複雜度為o 1 的演算法,該演算法刪除線性表中所有值為x的元素。一看就是典型的雙指標問題,於是我寫 如下 for i 0,j i 1 jif a j x else if a i x a i a j 這部分 是有問題的,如果出現在第一位的話就無法解...

王道資料結構課後習題 P37

3 設l為帶頭節點的單鏈表,編寫演算法實現從尾到頭反向輸出每個節點的值。我想到的是reverse一下 笑哭 想想這個就有點殺雞用牛刀的感覺 看了題解說是可以用遞迴 臥槽瞬間orz class solution 利用reverse將整個鍊錶倒置 void reverseoutput listnode ...

資料結構 王道課後題 線性表(1)

1.從順序表中是刪除最小元素,並返回該元素的值空出位置由最後一位填充。bool delete min sqlist l,elemtype value value l.data 0 int pos 0 for int i 0 i2.將順序表l所有元素逆置,並要求演算法空間複雜度為o 1 由於限制了空間...