版权声明:本文为博主原创学习笔记,如需转载请注明来源。 https://blog.csdn.net/SHU15121856/article/details/82561219
面试题31:栈的压入、弹出序列
输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1、2、3、4、5是某栈的压栈序列,序列4、5、3、2、1是该压栈序列对应的一个弹出序列,但4、3、5、1、2就不可能是该压栈序列的弹出序列。
用一个栈模拟一下压入和弹出的过程,两个序列不同步地向前走,当压入后栈顶出现要弹出的元素时就弹出,否则就继续压入。
#include<bits/stdc++.h>
using namespace std;
// 参数:
// pPush: 压栈序列
// pPop: 出栈序列
// nLength: 序列的长度
// 返回值:
// 这两个序列能否匹配
//const位于*的左侧,则const就是用来修饰指针所指向的变量,即指针指向为常量
//如果const位于*的右侧,const就是修饰指针本身,即指针本身是常量
bool IsPopOrder(const int* pPush, const int* pPop, int nLength) {
bool bPossible = false;//初始:不能匹配
//输入合法性检查
if(pPush != nullptr && pPop != nullptr && nLength > 0) {
//定义两个用来移动的指针,保留之前的指针用来比较
const int* pNextPush = pPush;
const int* pNextPop = pPop;
std::stack<int> stackData;//用一个STL栈来模拟
//只要没有移动出序列(这两个序列一样长),就要继续判断
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;
}
int main() {
const int nLength = 5;
int push[nLength] = {1, 2, 3, 4, 5};
int pop[nLength] = {3, 5, 4, 2, 1};
cout<<boolalpha<<IsPopOrder(push,pop,nLength);
return 0;
}
面试题32:从上到下打印二叉树
就是层序遍历二叉树,用队列。初始时候树根入队,循环中每次将队头取出来输出,然后将其左右孩子入队,直至队空。本质是广度优先遍历有向图。
#include<bits/stdc++.h>
#include "..\Utilities\BinaryTree.h"
using namespace std;
//输入二叉树根结点,输出从这里开始的其层序遍历结果
void PrintFromTopToBottom(BinaryTreeNode* pRoot) {
if(pRoot == nullptr)//输入非空校验
return;
//使用STL的deque(双端队列),其实只要是普通的队列就够了
deque<BinaryTreeNode *> dequeTreeNode;
dequeTreeNode.push_back(pRoot);//根节点从后入队
//只要队列非空,就一直做
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);
}
}
// 10
// / \
// 6 14
// /\ /\
// 4 8 12 16
int main() {
BinaryTreeNode* pNode10 = CreateBinaryTreeNode(10);
BinaryTreeNode* pNode6 = CreateBinaryTreeNode(6);
BinaryTreeNode* pNode14 = CreateBinaryTreeNode(14);
BinaryTreeNode* pNode4 = CreateBinaryTreeNode(4);
BinaryTreeNode* pNode8 = CreateBinaryTreeNode(8);
BinaryTreeNode* pNode12 = CreateBinaryTreeNode(12);
BinaryTreeNode* pNode16 = CreateBinaryTreeNode(16);
ConnectTreeNodes(pNode10, pNode6, pNode14);
ConnectTreeNodes(pNode6, pNode4, pNode8);
ConnectTreeNodes(pNode14, pNode12, pNode16);
PrintFromTopToBottom(pNode10);
DestroyTree(pNode10);
return 0;
}