面試題6:重建二叉樹
題目:輸入某二叉樹的前序和中序遍歷的結果,請重建出該二叉樹。假設輸入的前序遍歷和中序遍歷的結果中都不含重複的數字。假如輸入前序遍歷序列{1,2,4,7,3,5,6,8}和中序遍歷序列{4,7,2,1,5,3,8,6}。二叉樹結點的定義如下:
struct BinaryTreeNode
{
int m_nValue;
BinaryTreeNode* m_pLeft;
BinaryTreeNode* m_pRight;
};
我們可以寫出如下的遞歸代碼根據前序和中序遍歷的順序確定二叉樹結構:
BinaryTreeNode* Construct(int* preorder,int* inorder,int length)
{
if(preorder == NULL || inorder == NULL || length <= 0)
return NULL;
return ConstructCore(preorder,preorder+length-1,
inorder,inorder+length-1);
}
BinaryTreeNode* ConstructCore
(
int* startPreorder,int* endPreorder,
int* startInorder,int*endInorder
)
{
//前序遍歷序列的第一個數字是根結點的值
int rootValue = startPreorder[0];
BinaryTreeNode* root = new BinaryTreeNode();
root->m_nValue = rootValue;
root->m_pLeft=root->m_pRight=NULL;
if(startPreorder == endPreorder)
{
if(startInorder == endInorder
&& *startPreorder == *startInorder)
return root;
else
throw std::exception("Invalid input.");
}
//在中序遍歷中找到根結點的值
int* rootInorder = startInorder;
while(rootInorder<=endInorder && *rootInorder != rootValue)
++rootInorder;
if(rootInorder == endInorder && *rootInorder != rootValue)
throw std::exception("Invalid input.");
int leftLength=rootInorder-startInorder;
int* leftPreorderEnd = startPreorder+leftLength;
if(leftLength>0)
{
//構建左子樹
root->m_pLeft=ConstructCore(startPreorder + 1,
leftPreorderEnd,startInorder,rootInorder-1);
}
if(leftLength<endPreorder-startPreorder)
{
//構建右子樹
root->m_pRight = ConstructCore(leftPreorderEnd+1,endPreorder,rootInorder+1,endInorder);
}
return root;
}
在函數ConstructCore中,我們先根據前序遍歷序列的第一個數字創建根結點,接下來在中序遍歷序列中找到根結點的位置,這樣就能確定左、右子樹結點的數量。在前序遍歷和中序遍歷的序列中劃分了左、右子樹結點的值之後,我們就可以遞歸地調用函數ConstructCore,去分別構建它的左右子樹。
面試題7:用兩個棧實現隊列
題目:用兩個棧實現一個隊列。隊列的聲明如下,請實現它的兩個函數appendTail和deleteHead,分別完成在隊和尾部插入結點和在隊列頭刪除結點的功能。
template <typename T> class CQueue
{
public:
CQueue(void);
~CQueue(void);
void appendTail(const T& node);
T deleteHead();
private:
stack<T> stack1;
stack<t> stack2;
}
template<typename T> void CQueue<T>::appendTail(const T& element)
{
stack1.push(element);
}
template<typename T> T CQueue<T>::deleteHead()
{
if(stack2.size()<=0)
{
while(stack1.size()>0)
{
T& data =stack1.top();
stack1.pop();
stack2.push(data);
}
}
if(stack2.size()==0)
throw new exception("queue is empty");
T head = stack2.top();
stack2.pop();
return head;
}
參考書籍《劍指Offer》