面試中,最常見是資料結構就是二叉樹和鍊錶了,其中和二叉樹有關的常見面試題主要是:樹的前序遍歷、中序遍歷、後序遍歷、分層遍歷、樹的節點數、樹的葉子節點數、樹的第k層節點數、樹的深度、樹的寬度、平衡二叉樹的判定、完全二叉樹的判定、滿二叉樹的判定、由前序中序反推後序遍歷、由前序中序重建二叉樹,處理這些問題基本思想無外乎是「遍歷+遞迴」。
關於樹的遍歷,遞迴方式太傻太天真,但也是最基本的思想,實現**網上資料可謂是汗牛充棟,在此就不贅述了。
下面僅列舉了非遞迴實現樹的前序、中序以及後序遍歷,由於筆者對**有潔癖,最不能忍受乙個while迴圈裡再巢狀另外乙個while迴圈(網上千篇一律的實現**方式),雖然二者的思想都是一致的,但筆者的實現方式更為直觀易懂,故此處的版本都只借助乙個棧、乙個while迴圈:
前序非遞迴遍歷:
void preordertrasenonrecursion(btree* t)
}
中序非遞迴遍歷:
void inordertrasenonrecursion(btree* t)
else}}
前序和中序的非遞迴遍歷都很好理解,我就不再浪費口舌筆墨了,要是真看不懂,請回去把嚴蔚敏那本《資料結構》再啃一遍、兩遍、三遍……要是還看不懂,我只能懷著無比沉重的心情告訴你乙個非常不幸的訊息:「對不起,你不適合這個行業!」
後序非遞迴遍歷:後序非遞迴遍歷稍微比較難理解些,但是你如果對前序和中序遍歷思想已經融會貫通了,其實也就那樣:
從根節點開始,只要當前節點存在,或者棧不為空,則重複下面操作:
(1)從當前節點開始,進棧並走左子樹,直到左子樹為空。
(2)如果棧頂節點的右子樹為空,或者棧頂節點的右孩子為剛訪問過的節點,
則退棧並訪問,然後置當前節點指標為空。
(3)否則走右子樹。
void postordertrasenonrecursion(btree* t)
else
else}}}
還有一種網上流傳的後序遍歷的方式是借助於兩個棧,乙個棧用來遍歷,另乙個棧儲存遍歷到的結點,最後一起出棧,就是後序遍歷結果。
void postordertrasenonrecursion2(btree* t)
while(!svisit.empty())
}
分層遍歷:通過分層遍歷可實現統計樹的深度、每一層節點數、樹的最大寬度等要求。基本解法想必你也知道了,就是借助乙個佇列,進行入隊、出隊操作,如下面的二叉樹,要是一口氣全部列印所有節點,即輸出:
1 2 3 4 5 6 7。
再進一步考察,如何實現將二叉樹按層列印,即每一行列印二叉樹的每一層樹節點,輸出為:
12 3
4 5 6
7
1/ \ 2 3
/ \ \
4 5 6/
7 這就需要再基本的分層遍歷基礎上再做些手腳了,
下面是乙個簡單的例子:
//分層列印節點,每一行為一層,返回該二叉樹的層數
int depthtrase(btree* t)
{ if(t==null)
return 0;
vectorv;
v.push_back(t);
int front=0;//該層的開始節點下標
int rear=0;//該層結束節點下標
int last=1;//所有已遍歷的節點個數
int level=0;//層次數
while(rear < v.size())
{ bnode* p = v[rear++];
if(p->lchild)
v.push_back(p->lchild);
if(p->rchild)
v.push_back(p->rchild);
if(rear>=last)
{ //列印每一層節點
for(int i=front;i下面再介紹幾個二叉樹中的高階應用:
1、根節點到r節點的路徑:
後序遍歷時訪問到r節點時,棧中的所有的節點均為r節點的祖先,這些祖先構成根節點到r節點的路徑。
由此引出下面的第2個問題……
2、求二叉樹中兩個節點的最低公共祖先節點:
遞迴解法效率很低,有很多重複的遍歷,不再贅述。
非遞迴解法:
先求從根節點到兩個節點的路徑,然後再比較對應路徑的節點,最後乙個相同的節點也就是他們在二叉樹中的最低公共祖先節點,問題轉換為求兩個單鏈表的最後乙個公共節點。
3、二叉樹節點最大距離
姑且定義
"距離"為兩節點之間邊的個數。求二叉樹中相距最遠的兩個節點之間的距離,如下圖:
對此問題做了詳細解答,指出了《程式設計之美》中其解法的不足之處,並提出了筆者的解法。
二叉樹面試題
1.求二叉樹節點個數 可以使用遞迴解決。將問題分解為求根節點 左子樹的節點數 右節點的節點數。實現 public size t size private size t size node root 2.求頁節點個數 頁節點 左右子樹都為空的節點被稱為頁節點,使用遞迴遍歷,當碰到乙個左右子樹為空的節點...
面試題 二叉樹
面試題 二叉樹 1.重建二叉樹 前序 中序 treenode reconstructbinarytree vector pre,vector vin treenode root new treenode pre 0 int pos 0 for pos pre left,vin left,pre ri...
二叉樹 面試題2
輸入某二叉樹的前序遍歷和中序遍歷的結果,請重建出該二叉樹。假設輸入的前序遍歷和中序遍歷的結果中都不含重複的數字。例如輸入前序遍歷序列和中序遍歷序列,則重建二叉樹並返回。前序遍歷 dlr 中序遍歷 ldr 重建過程用遞迴演算法比較簡單 public static treenode reconstruc...