這是一道面試題
由前序遍歷和中序遍歷重建二叉樹(前序序列:1 2 3 4 5 6 - 中序序列:3 2 4 1 6 5)
資料不含重複值
這個可以分析一下
前序遍歷序列
1 2 3 4 5 6
,前序遍歷規則是根--左--右
中序遍歷序列
3 2 4 1 6 5
,中序遍歷規則是左--根--右
由前序遍歷可知根節點為第乙個元素1,在中序遍歷序列中找到1對應位置,
則1的左邊就是左子樹324,右邊就是右子樹56;
在找到前序遍歷序列中從第二個位置開始往後找相同數目的節點為左子樹234,剩餘的就是右子樹序列65,
再根據前序遍歷規則可知,左子樹序列裡第乙個就是左子樹的根節點2,右子樹序列裡的第乙個就是有右子樹的根節點5,
再根據中序遍歷序列可知,左子樹的根節點2左邊的一定是以其為根節點的左子樹序列3,右邊就是以其為根節點的右子樹序列4,
右子樹的根節點5左邊的一定是以其為根節點的右子樹序列6,直至序列為空,就可以完整重建二叉樹了
如圖:**
**實現:
定義節點:
#include#includeusing namespace std;
//定義一棵二叉樹的節點
struct btreenode
;
函式實現
btreenode * rebuildtree(int* preorder,int* inorder,int length)
else }
btreenode *rebuildcore(int *startpreorder,int *endpreorder,int *startinorder,int *endinorder)
//4.根據此根節點的值在中序遍歷中找此次節點的位置
int * rootin = startinorder;
while(*startpreorder != *rootin)
//6.根據此根節點在中序遍歷中的位置,遞迴還原左子樹
int leftlength = rootin-startinorder;
if(leftlength>0)
//此處千萬不要錯寫成 else if 因為若是這樣,判斷滿足上面的遞迴條件,則進入遞迴還原左子樹,當左子樹完全被還原後,再調回這個點的時候,就不會繼續執行 else if 語句了,因為上面的條件已經滿足,所以右子樹將沒辦法還原了
if(leftlength+startinorder < endinorder)//左子樹長度加上中序的起始位置後若仍然小於整個中序長度則說明該節點還存在右子樹,所以繼續遞迴還原右子樹
return root;
}
後序遍歷
void postorder(btreenode *root)
if(root->right != null)
if(root != null) }
測試**
int main()
; int inorder = ;
btreenode *root = rebuildtree(&preorder[0],&inorder[0],6);
postorder(root);//324651
cout<
測試結果:
前序遍歷和中序遍歷重建二叉樹
根據先序序列和中序序列的特點我們可以知道 1 先序的第乙個節點是根節點 2 在中序序列中,根結點前邊的結點都是左子樹中的,根結點右邊的結點都是右子樹中的 3 通過左右子樹的中序序列帶入前序序列可以求出左右子樹的前序序列 4 左右子樹的前序序列第乙個元素分別是根節點的左右孩子 5 可以遞迴上述步驟來重...
由前序遍歷和中序遍歷重建二叉樹
唯一的難點就是確定當前節點的左子樹的根節點和右子樹的根節點分別在前序遍歷陣列的位置。例如 先序遍歷陣列pre 1 2 3 4 5 6 7 中序遍歷陣列in 3 2 4 1 6 5 7 1是當前根節點,它在pre中的位置 pre start 0接著在in中找到1的位置,即分割點 j 3當前樹根所囊括的...
根據前序遍歷和中序遍歷重建二叉樹
輸入某二叉樹的前序遍歷和中序遍歷的結果,請重建出該二叉樹。假設輸入的前序遍歷和中序遍歷的結果中都不含重複的數字。例如輸入前序遍歷序列和中序遍歷序列,則重建二叉樹並返回。class treenode public class s2 public treenode reconstruct int pre...