剑指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() + "、");
}
}
}
相关文章推荐
- 剑指offer面试题5-从尾到头打印链表/6-重建二叉树
- 《剑指offer》---从尾到头打印链表 和 重建二叉树
- 从尾到头打印链表
- 从尾到头打印链表
- 1、从尾到头打印链表
- 从尾到头打印链表
- 剑指offer(C++)——从尾到头打印链表
- 剑指offer 面试题5:从尾到头打印链表
- 九度 从尾到头打印链表
- 从尾到头打印链表
- 【面试题5】从尾到头打印链表
- 从尾到头打印链表<剑指offer>
- 05:从尾到头打印链表
- 牛客网-Offer-从尾到头打印链表
- 九度OJ-题目1511:从尾到头打印链表
- 剑指-从尾到头打印链表
- 剑指offer(一)之从尾到头打印链表
- 05_PrintListInReversedOrder从尾到头打印链表
- 从尾到头打印链表
- 从尾到头打印链表