面試題22:棧的壓入、彈出序列
題目:輸入兩個整數序列,第一個序列表示棧的壓入順序,請判斷第二個序列是否爲該棧的彈出順序。假設壓入棧的所有數字均不相等。例如序列1、2、3、4、5是某棧的壓入順序,序列4、5、3、2、1是該壓棧序列對應的一個彈出序列,但4、3、5、1、2就不可能是該棧序列的彈出序列。
判斷一個序列是不是棧的彈出序列的規律:如果下一個彈出的數字剛好是棧頂數字,那麼直接彈出。如果下一個彈出的數字不在棧頂,我們把壓棧序列中還沒有入棧的數字壓入輔助棧,直到把下一個需要彈出的數字壓入棧頂爲止。如果所有的數字都壓入棧了仍然沒有找到下一個彈出的數字,那麼該序列不可能是一個彈出序列。
bool IsPopOrder(const int* pPush,const int* pPop,int nLength)
{
bool bPossible = false;
if(pPush != NULL && pPop != NULL && nLength > 0)
{
const int* pNextPush = pPush;
const int* pNextPop = pPop;
std::stack<int> stackData;
while(pNextPop - pPop < nLength)
{
while(stackData.empty() || stackData.top() != *pNextPop)
{
if(pNextPush - pPush == nLength)
break;
stackData.push(*pNextPush);
pNextPush++;
}
if(stackData.top() != *pNextPop)
break;
stackData.pop();
pNextPop++;
}
if(stackData.empty() && pNextPop - pPop == nLength)
bPossible = true;
}
return bPossible;
}
面試題23:從上往下打印二叉樹
題目:從上往下打印出二叉樹的每個結點,同一層的結點按照從左到右的順序打印。例如輸入圖4.5中的二叉樹,則依次打印出8、6、10、5、7、9、11。
二叉樹結點的定義如下:
struct BinaryTreeNode
{
int m_nValue;
BinaryTreeNode* m_pLeft;
BinaryTreeNode* m_pRight;
};
從上到下打印二叉樹的規律:每次打印一個結點的時候,如果該結點有子結點,則把該結點的子結點放到一個隊列的末尾。接下來到隊列的頭部取出最早進入隊列的結點,重複前面的打印操作,直至隊列中所有的結點都被打印出來爲止。
void PrintFromTopToBottom(BinaryTreeNode* pTreeRoot)
{
if(!pTreeRoot)
return;
std::deque<BinaryTreeNode *> dequeTreeNode;
dequeTreeNode.push_back(pTreeRoot);
while(dequeTreeNode.size())
{
BinaryTreeNode *pNode = dequeTreeNode.front();
dequeTreeNode.pop_front();
printf("%d",pNode->m_nValue);
if(pNode->m_pLeft)
dequeTreeNode.push_back(pNode->m_pLeft);
if(pNode->m_pRight)
dequeTreeNode.push_back(pNode->m_pRight);
}
}
面試題24:二叉搜索樹的後序遍歷序列
題目:輸入一個整數數組,判斷數組是不是某二叉搜索樹的後序遍歷的結果。如果是則返回true,否則返回false。假設輸入的數組的任意兩個數字都互不相同。
在後序遍歷得到的序列中,最後一個數字是樹的根結點的值。數組中前面的數字可以分爲兩部分:第一部分是左子樹結點的值,它們都比根結點的值小;第二部分是右子樹結點的值,它們都比根結點的值大。
bool VerifySquenceOfBst(int sequence[],int length)
{
if(sequence == NULL || length <= 0)
return false;
int root = sequence[length -1];
//在二叉搜索樹中左子樹的結點小於根結點
int i = 0;
for(;i < length -1;++i)
{
if(sequence[i] > root)
break;
}
//在二叉搜索樹中右子樹的結點大於根結點
int j=i;
for(;j< length-1;++j)
{
if(sequence[j] < root)
return false;
}
//判斷左子樹是不是二叉搜索樹
bool left = true;
if(i > 0)
left=VerifySquenceOfBst(sequence,i);
//判斷右子樹是不是二叉搜索樹
bool right = true;
if(i < length -1 )
right = VerifySquenceOfBst(sequence+i,length-i-1);
return (left && right);
}
參考資料《劍指Offer》