题目来源剑指offer
(1)输入一个链表的头节点,从尾到头打印出每个节点的值:
链表节点定义:
struct ListNode
{
int key;
ListNode pNext;
};
思路:
可将链表的指针方过来,改变链表的方向就可以实现,但是这会改变链表的结构,需要询问考官是否可以。这给出两种不改变结构的方法
1、处理这种“后进先出”问题,可通过栈实现。每通过一个节点,将节点放入一个栈中。当遍历完整个链表后,从栈顶开始逐个输出节点值。
void list(Listnode* pHead)
{
std::stack<ListNode*>nodes;
ListNode* pNodde=pHead;
while(pNode !=nullptr)
{
nodes.push(pNode);
pNode=pNode->pNext
}
while(!nodes.empty())
{
pNode=nodes.top();
printf("%d\t",pNode->m_nBValue);
nodes.pop();
}
}
2、通过递归,每到一个节点,递归输出后面的节点,再输出自身
void list2(ListNode* pHead)
{
if(pHead!=nullptr)
{
if(pHead->m_pNext!=nullptr)
{
list2(pHead->m_pNext);
}
printf(%d\t",pHead->m_nBValue);
}
}
(2)给出二叉树的前序遍历和中序遍历结果,重建二叉树。假设不存在重复数字,前序遍历结果{1,2,4,7,3,5,6,8}中序遍历结果(4,7,2,1,5,3,8,6}
二叉树节点定义:
struct BinaryTreeNode
{
int m_nBValue;
BinaryTreeNode* m_pLeft;
BinaryTreeNode* m_pRight;
}
知识点:
- 前序遍历:先访问根节点,再访问左子节点,最后访问右子节点,如图二叉树访问结果:1,2,4,5,3,6,7
- 中序遍历:先访问左子节点,再访问根节点,最后访问右子节点,如图二叉树访问结果:4,2,5,1,6,3,7
- 后续遍历:先访问左子节点,再访问右子节点最后,访问根节点,如图二叉树访问结果:4,5,2,6,7,3,1
思路:可依据结果还原二叉树:
前序遍历1就是根节点的值,中序遍历可知,4,7,2组成了左子树,5,3,8,6组成右子树,同样的方法可以知道每个数的位置
代码实现:
BinaryTreeNode* construct(int* preorder,int* inorder,int length)
{
if(preorder==nullptr || inorder==nullptr || length<=0)
{
return nullptr;
}
return constructCore(preorder,preorder+length=1,inorder,inorder+length-1);
}
BinaryTreeNode* constructCore(int* startPreorder,int* endPreorder,int* startInorder,int* endInorder)
{
//前序遍历第一个值是根节点的值
int rootBValue=startPreorder[0];
BinaryTreeNode* root=new BinaryTreeNode();
root->m_nValue=rootValue;
root->m_pLeft=root->m_pRight=nullptr;
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>o)
{
root->m_pLeft=constructCore(startPreorder+1,leftPreorderEnd,startInorder,rootInorder-1);
)
if(leftLength<endPreorder-startPreorder)
{
root->m_pRight=constructCore(startPreorder+1,endPreorder,rootInorder+1,endInorder);
}
}