您的位置:首页 > Web前端

剑指Offer笔记—— 从尾到头打印链表 重建二叉树

2017-06-30 18:20 423 查看

3、面试题5:从尾到头打印链表

题目大致为:

    输入一个链表的头结点,从未到头反过来打印每个结点的值。

思路:

    题目的要求是进行从尾到头输出,而链表的查找只能是顺序查找,栈的结构满足这样的条件:先进后出。同样,也可以使用递归的方式求解。

Java代码:

链表类:

[java] view
plain copy

package org.algorithm.pointtooffer;  

  

/** 

 * 链表的节点 

 *  

 * @author dell 

 *  

 */  

public class ListNode {  

    private int value;  

    private ListNode next;  

  

    public ListNode(int value) {  

        this.value = value;  

    }  

  

    public ListNode(int value, ListNode next) {  

        this.value = value;  

        this.next = next;  

    }  

  

    public void setValue(int value) {  

        this.value = value;  

    }  

  

    public void setNext(ListNode next) {  

        this.next = next;  

    }  

  

    public int getValue() {  

        return this.value;  

    }  

  

    public ListNode getNext() {  

        return this.next;  

    }  

  

}  

Java实现:

[java] view
plain copy

package org.algorithm.pointtooffer;  

  

import java.util.Stack;  

  

/** 

 * 面试题5:从尾到头打印链表 

 *  

 * @author dell 

 *  

 */  

public class Item05 {  

    /** 

     * 测试 

     *  

     * @param args 

     */  

    public static void main(String args[]) {  

        // 构建链表  

        ListNode head = new ListNode(0);  

        ListNode node_one = new ListNode(1);  

        ListNode node_two = new ListNode(2);  

        ListNode node_three = new ListNode(3);  

        ListNode node_four = new ListNode(4);  

        head.setNext(node_one);  

        node_one.setNext(node_two);  

        node_two.setNext(node_three);  

        node_three.setNext(node_four);  

        node_four.setNext(null);  

        System.out.println("第一种方式,递归实现:");  

        printListReverse_1(head);  

        //换行  

        System.out.println();  

        System.out.println("第二种方式,非递归实现:");  

        printListReverse_2(head);  

    }  

  

    /** 

     * 用递归实现 

     *  

     * @param head 

     */  

    public static void printListReverse_1(ListNode head) {  

        if (head != null) {  

            if (head.getNext() != null) {  

                printListReverse_1(head.getNext());  

            }  

            System.out.print(head.getValue() + "、");  

        }  

    }  

  

    /** 

     * 用栈实现 

     *  

     * @param head 

     */  

    public static void printListReverse_2(ListNode head) {  

        Stack<Integer> s = new Stack<Integer>();  

        ListNode p = head;  

        // 进栈  

        while (p != null) {  

            s.push(p.getValue());  

            p = p.getNext();  

        }  

  

        // 出栈  

        while (!s.isEmpty()) {  

            System.out.print(s.pop() + "、");  

        }  

        System.out.println();  

    }  

}  

4、面试题6:重建二叉树

题目大致为:

    已知前序遍历序列和中序遍历序列,要求重建二叉树

二叉树的结点定义:

 

[java] view
plain copy

package org.algorithm.pointtooffer;  

  

public class BinaryTreeNode {  

    private int value;  

    private BinaryTreeNode left;  

    private BinaryTreeNode right;  

  

    public BinaryTreeNode(int value) {  

        this.value = value;  

    }  

  

    public BinaryTreeNode(int value, BinaryTreeNode left, BinaryTreeNode right) {  

        this.value = value;  

        this.left = left;  

        this.right = right;  

    }  

  

    public int getValue() {  

        return value;  

    }  

  

    public void setValue(int value) {  

        this.value = value;  

    }  

  

    public BinaryTreeNode getLeft() {  

        return left;  

    }  

  

    public void setLeft(BinaryTreeNode left) {  

        this.left = left;  

    }  

  

    public BinaryTreeNode getRight() {  

        return right;  

    }  

  

    public void setRight(BinaryTreeNode right) {  

        this.right = right;  

    }  

  

}  



思路:

    如上图所示,在前序遍历的序列中第一个就是树的根结点,此时再在中序遍历的序列里查找这个根结点,则中序遍历的序列里根结点左侧的就是左子树,右侧的就是右子树,再对左右子树进行同样的操作,此时可以使用递归实现,这样便能构造出这个二叉树。

Java代码:

[java] view
plain copy

package org.algorithm.pointtooffer;  

  

/** 

 * 面试题6:重建二叉树 

 *  

 * @author dell 

 *  

 */  

public class Item06 {  

    public static void main(String args[]) {  

        // 二叉树的前序遍历  

        int preOrder[] = { 1, 2, 4, 7, 3, 5, 6, 8 };  

        // 二叉树的中序遍历  

        int inOrder[] = { 4, 7, 2, 1, 5, 3, 8, 6 };  

          

        BinaryTreeNode root = constructTree(preOrder, inOrder);  

        printPostOrder(root);  

    }  

  

    public static BinaryTreeNode constructTree(int preOrder[], int inOrder[]) {  

        // 根据前序遍历创建根结点  

        BinaryTreeNode root = new BinaryTreeNode(preOrder[0]);  

        root.setLeft(null);  

        root.setRight(null);  

  

        int leftNum = 0;//左子树的结点个数  

  

        // 在中序中找到根节点  

        for (int i = 0; i < inOrder.length; i++) {  

            if (inOrder[i] == root.getValue()) {  

                break;  

            } else {  

                leftNum++;  

            }  

        }  

        int rightNum = preOrder.length - 1 - leftNum;  

  

        // 左子树不为空  

        if (leftNum > 0) {  

            //构造左子树的前序和中序遍历序列  

            int leftPreOrder[] = new int[leftNum];  

            int leftInOrder[] = new int[leftNum];  

            for (int i = 0; i < leftNum; i++) {  

                leftPreOrder[i] = preOrder[i + 1];  

                leftInOrder[i] = inOrder[i];  

            }  

            //递归构造左子树  

            BinaryTreeNode leftRoot = constructTree(leftPreOrder, leftInOrder);  

            root.setLeft(leftRoot);  

        }  

          

        //右子树不为空  

        if (rightNum > 0) {  

            //构造右子树的前序和中序遍历序列  

            int rightPreOrder[] = new int[rightNum];  

            int rightInOrder[] = new int[rightNum];  

            for (int i = 0; i < rightNum; i++) {  

                rightPreOrder[i] = preOrder[leftNum + i + 1];  

                rightInOrder[i] = inOrder[leftNum + i + 1];  

            }  

            //递归构造右子树  

            BinaryTreeNode rightRoot = constructTree(rightPreOrder,  

                    rightInOrder);    

            root.setRight(rightRoot);  

        }  

        return root;  

    }  

      

    /** 

     * 二叉树的后序遍历(递归实现) 

     * @param root 树的根结点 

     */  

    public static void printPostOrder(BinaryTreeNode root) {  

        if (root != null) {  

            printPostOrder(root.getLeft());  

            printPostOrder(root.getRight());  

            System.out.print(root.getValue() + "、");  

        }  

    }  

}  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: