剑指offer6&7&8&9-链表&树&栈
Posted lyeeer
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了剑指offer6&7&8&9-链表&树&栈相关的知识,希望对你有一定的参考价值。
题目6
输入一个链表的头节点,从尾到头反过来打印出每个结点的值
思路
1.使用递归。逆序打印a->b->c->d,可以先逆序打印b->c->d(看成新的链表),再打印a;那么同样逆序可以先逆序打印c->d,再打印b;直到打印到尾节点。
2.使用栈。栈具有后进先出的特点,刚好符合逆序要求。遍历链表时将值按顺序放入栈中,最后依次出栈。
解法
class ListNode{
int m_nKey;
ListNode m_pNext;
}
//递归法
public void PrintListReversingByRecursive(ListNode listNode) {
if(listNode != null) {
if(listNode.m_pNext!=null) {
PrintListReversingByRecursive(listNode.m_pNext);
}
System.out.print(listNode.m_nKey+" ");
}
}
//栈
public void PrintListReversingByStack(ListNode listNode) {
Stack<ListNode> stack=new Stack<ListNode>();
while(listNode != null) {
stack.push(listNode);
listNode=listNode.m_pNext;
}
while(!stack.empty()) {
System.out.print(stack.pop().m_nKey+" ");
}
}
题目7
根据二叉树的前序遍历和中序遍历的结果,重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。
思路
前序遍历-根左右
中序遍历-左根右
后序遍历-左右根
前序遍历的第一个值为根节点的值,使用这个值将中序遍历结果分成两部分,左部分为树的左子树中序遍历结果,右部分为右子树中序遍历结果。
然后不断根据左子树的中序和前序遍历结果构造左子树,右子树同理。
不断递归,得到结果。
解法
class BinaryTreeNode{ int m_nValue; BinaryTreeNode m_nLeft; BinaryTreeNode m_nRight; BinaryTreeNode(int m_nValue){ this.m_nValue=m_nValue; } } public BinaryTreeNode Construct(int preorder[], int inorder[]) { if(preorder==null || inorder==null) { return null; } return ConstructCore(preorder, 0, preorder.length-1, inorder, 0, inorder.length-1); } public BinaryTreeNode ConstructCore(int preorder[], int startPreorder, int endPreorder, int inorder[], int startInorder, int endInorder) { //停止递归的条件 if(startPreorder>endPreorder || startInorder>endInorder) { return null; } //前序遍历的第一个数字是根节点 BinaryTreeNode root=new BinaryTreeNode(preorder[startPreorder]); for(int i=startInorder;i<=endInorder;i++) { if(preorder[startPreorder]==inorder[i]) { //根据左子树的前序和中序遍历,构建左子树。i-startInorder为中序排列中左子树节点的个数 root.m_nLeft=ConstructCore(preorder,startPreorder+1, startPreorder+(i-startInorder), inorder, startInorder, i-1); //根据右子树的前序和中序遍历,构建右子树 root.m_nRight=ConstructCore(preorder, startPreorder+1+(i-startInorder), endPreorder, inorder, i+1, endInorder); } } return root; }
题目8
给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针。
思路
1.如果节点右子树不为空,那么该节点的下一个节点是右子树的最左节点。
2.如果右子树不为空,那么就是第一个左链接指向的树包含该节点的祖先节点。即沿着指向父节点的指针一路向上遍历,直到找到一个是它父节点的左子节点的节点。如果这个节点存在,那么这个节点的父节点就是下一个节点。
可以画出图来,找规律。
解法
public class TreeLinkNode{ int data; TreeLinkNode left=null; TreeLinkNode right=null; TreeLinkNode next=null; TreeLinkNode(int data){ this.data=data; } } public TreeLinkNode getNext(TreeLinkNode tNode) { if(tNode.right!=null) { TreeLinkNode node=tNode.right; while(node.left!=null) { node=node.left; } return node; } else { while(tNode.next!=null) { TreeLinkNode parent=tNode.next; if(parent.left==tNode) { return parent; } tNode=tNode.next; } } return null; }
题目9
用两个栈来实现一个队列,完成队列的 Push 和 Pop 操作。
思路
栈:后进先出
队列:先进先出
解答
扩展
以上是关于剑指offer6&7&8&9-链表&树&栈的主要内容,如果未能解决你的问题,请参考以下文章