该文章几乎包含了所有与二叉树相关的基础面试题,其中包括二叉树的四种遍历方法:前序遍历,中序遍历,后续遍历,层次遍历。

算法题包括:

二叉树的序列化和反序列化

给定一颗二叉搜索树,请找出其中的第k大的结点。例如, 5 / \ 3 7 /\ /\ 2 4 6 8 中, 按结点数值大小顺序第三个结点的值为4。

package test;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.PriorityQueue;
import java.util.Queue; import org.junit.Test; class TreeNode {
int val = 0;
TreeNode left = null;
TreeNode right = null; public TreeNode(int val) {
this.val = val; } } public class Solution {
/**
* 二叉树的前序序列化
*
* @param root
* @return
*/
String Serialize(TreeNode root) {
if (root == null)
return null;
StringBuilder str = new StringBuilder();
SerializeRe(root, str);
return str.toString();
} /**
* 二叉树的前序序列化递归方法
*
* @param root
* @param str
*/
public void SerializeRe(TreeNode root, StringBuilder str) {
if (root == null) {
str.append("#,");
return;
} else {
str.append(root.val);
str.append(",");
SerializeRe(root.left, str);
SerializeRe(root.right, str);
}
return;
} /**
* 前序反序列化
*
* @param str
* @return
*/
TreeNode Deserialize(String str) {
if (str == null || str.length() == 0 || str.equals("#"))
return null;
String[] value = str.split(",");
return DeserializeRe(value);
} int index = 0; /**
* 前序反序列化递归方法
*
* @param str
* @return
*/
public TreeNode DeserializeRe(String[] str) {
TreeNode root = new TreeNode(-1);
if (str[index].equals("#") || index > str.length) {
return null;
}
root.val = Integer.valueOf(str[index]);
index++;
root.left = DeserializeRe(str);
index++;
root.right = DeserializeRe(str);
return root;
} /**
* 根据数组从上到下构造一棵二叉树(即完全二叉树)
*
* @param a
* @param index
* @return
*/
public TreeNode buildTreeLevel(int[] a) {
if (a == null || a.length == 0)
return null;
return buildTreeLevelRe(a, 0);
} private TreeNode buildTreeLevelRe(int[] a, int index) {
TreeNode root = new TreeNode(-1);
root.val = a[index];
if (index * 2 + 1 <= a.length - 1) {
root.left = buildTreeLevelRe(a, index * 2 + 1);
}
if (index * 2 + 2 <= a.length - 1) {
root.right = buildTreeLevelRe(a, index * 2 + 2);
}
return root;
} /**
* 前序遍历二叉树
*
* @param root
*/
public void preOderTree(TreeNode root) {
if (root == null)
return;
System.out.println(root.val);
preOderTree(root.left);
preOderTree(root.right);
return;
} /**
* 中序遍历二叉树
*
* @param root
*/
public void inOderTree(TreeNode root) {
if (root == null)
return;
inOderTree(root.left);
System.out.println(root.val);
inOderTree(root.right);
return;
} /**
* 后序遍历二叉树
*
* @param root
*/
public void postOderTree(TreeNode root) {
if (root == null)
return;
postOderTree(root.left);
postOderTree(root.right);
System.out.println(root.val);
return;
} /**
* 层次遍历二叉树
*
* @param root
*/
public void levelOderTree(TreeNode root) {
if (root == null)
return;
Queue<TreeNode> nodes = new LinkedList<TreeNode>();
nodes.add(root);
while (!nodes.isEmpty()) {
TreeNode node = nodes.poll();
System.out.println(node.val);
if (node.left != null) {
nodes.add(node.left);
}
if (node.right != null) {
nodes.add(node.right);
}
}
} /**
* 给定一颗二叉搜索树,请找出其中的第k大的结点。例如, 5 / \ 3 7 /\ /\ 2 4 6 8 中, 按结点数值大小顺序第三个结点的值为4。
* 解法一:时间复杂度O(k),空间复杂度O(1)
*
* @param root
* @param k
* @return
*/
int count = 0;// 计数器 public TreeNode KthNodeRe(TreeNode root, int k) {
if (root != null) {
TreeNode node = KthNodeRe(root.left, k);
if (node != null)
return node;
count++;
if (count == k)
return root;
node = KthNodeRe(root.right, k);
if (node != null)
return node;
}
return null;
} ArrayList<TreeNode> arr = new ArrayList<TreeNode>(); /**
* 解法二:时间复杂度O(n),空间复杂度O(n)
*
* @param pRoot
* @param k
* @return
*/
public TreeNode KthNode(TreeNode pRoot, int k) {
if (pRoot == null || k <= 0)
return null;
InOder(pRoot);
return k > arr.size() ? null : arr.get(arr.size() - k);
} public void InOder(TreeNode pRoot) {
if (pRoot == null)
return;
InOder(pRoot.left);
arr.add(pRoot);
InOder(pRoot.right);
} /**
* 如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,
* 那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,
* 那么中位数就是所有数值排序之后中间两个数的平均值
* @param num
*/
private PriorityQueue<Integer> minHeap = new PriorityQueue<>();
private PriorityQueue<Integer> maxHeap = new PriorityQueue<Integer>(
new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o2 - o1;
}
});
public void Insert(Integer num) {
if (count % 2 == 0) {
// 1.新加入的元素先入到大根堆,由大根堆筛选出堆中最大的元素
maxHeap.offer(num);
int filteredMaxNum = maxHeap.poll();
// 2.筛选后的【大根堆中的最大元素】进入小根堆
minHeap.offer(filteredMaxNum);
} else {
// 1.新加入的元素先入到小根堆,由小根堆筛选出堆中最小的元素
minHeap.offer(num);
int filteredMinNum = minHeap.poll();
// 2.筛选后的【小根堆中的最小元素】进入大根堆
maxHeap.offer(filteredMinNum);
}
count++;
} public Double GetMedian() {
if (count % 2 == 0) {
return new Double((minHeap.peek() + maxHeap.peek())) / 2;
} else {
return new Double(minHeap.peek());
}
} @Test
public void testDeserialize() {
String str = "1,2,4,#,#,5,#,#,3,#,#";
TreeNode root = Deserialize(str);
preOderTree(root);
} @Test
public void testBuildTreePre() {
String str = "1,2,4,#,#,5,#,#,3,#,#";
TreeNode root = Deserialize(str);
// preOderTree(root);
String serialize = Serialize(root);
System.out.println(serialize);
} @Test
public void testBuildTreeLevel() {
int[] a = { 1, 2, 3, 4, 5 };
TreeNode root = buildTreeLevel(a);
inOderTree(root);
} @Test
public void testBuildTreeKthNode() {
int[] a = { 4, 2, 5, 1, 3 };
TreeNode root = buildTreeLevel(a);
inOderTree(root);
}
}

与二叉树有关的编程题的Java代码实现的更多相关文章

  1. 去哪儿网2017校招在线笔试(前端工程师)编程题及JavaScript代码

    编程题很简单.整个试卷结构为: 一.问答题: 对前端的理解,了解哪些框架库? 二.在线编程题:身份证分组 如下第一道:身份证分组 三.在线编程题:身份证分组.统计字符.酒店价格(三选二) 如下第二三四 ...

  2. hdu-5670 Machine(水题附上java代码)

    题目链接: Machine  Time Limit: 2000/1000 MS (Java/Others)  Memory Limit: 65536/65536 K (Java/Others) 问题描 ...

  3. 剑指Offer编程题(Java实现)——链表中环的入口结点

    题目描述 给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null. 思路一 迭代遍历链表,利用HashSet将每个结点添加到哈希表中,如果添加失败(重复遍历了这个结点即遇到环),输出 ...

  4. 剑指Offer编程题(Java实现)——删除链表中重复的结点

    题目描述 在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针. 例如,链表1->2->3->3->4->4->5 处理后 ...

  5. 剑指Offer编程题(Java实现)——复杂链表的复制

    题目描述 输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head.(注意,输出结果中请不要返回参数中的节点引用,否 ...

  6. 剑指Offer编程题(Java实现)——链表中倒数第k个结点

    题目描述 输入一个链表,输出该链表中倒数第k个结点. 注意: 该题目不可以用先反转链表再输出第k个结点的方式,因为反转链表会改变该结点的next指向 思路一 使用栈Stack倒序存储,顺序pop第k个 ...

  7. 剑指Offer编程题(Java实现)——从尾到头打印链表

    题目描述 输入一个链表,按链表值从尾到头的顺序返回一个ArrayList. 解题思路 思路一:使用头插法 使用头插法可以得到一个逆序的链表.遍历链表,每次将所遍历节点插入到链表的头部. 头结点和第一个 ...

  8. 剑指Offer编程题(Java实现)——数组中的重复数字

    题目描述 在一个长度为n的数组里的所有数字都在0到n-1的范围内. 数组中某些数字是重复的,但不知道有几个数字是重复的.也不知道每个数字重复几次.请找出数组中任意一个重复的数字. 例如,如果输入长度为 ...

  9. 剑指Offer编程题(Java实现)——两个链表的第一个公共结点

    题目描述: 输入两个链表,找出它们的第一个公共结点. 思路一: 设 A 的长度为 a + c,B 的长度为 b + c,其中 c 为尾部公共部分长度,可知 a + c + b = b + c + a. ...

随机推荐

  1. Eclipse中如何忽略报错的js文件

    https://jingyan.baidu.com/article/4f7d5712d3701a1a20192786.html

  2. mybatis3:Invalid bound statement (not found)

    最近在玩ssm框架搭建,突然发现最后的时候mybaits和SpringMvc进行整合的时候出现错误 Invalid bound statement (not found) 这个错误有可能出现在以下几个 ...

  3. Log4j与Log4j2

    完整的软件,日志是必不可少的.程序从开发.测试.维护.运行等环节,都需要向控制台或文件等位置输出大量信息.这些信息的输出,在很多时候是System.out.println()无法完成日志信息根据用途与 ...

  4. Jar程序使用MyBatis集成阿里巴巴druid连接池

    在写jar程序,而不是web程序的时候,使用mybatis作为持久层,可以集成POOLED连接池,而阿里的druid不能用,确实很郁闷.不过有办法. 首先准备好数据库配置文件 然后对Druid进行一个 ...

  5. Visual Studio 环境路径答疑!

    工程目录结构如下: Console │ Console.sln │ Console.VC.db │ ├─Console │ │ Console.cpp │ │ Console.vcxproj │ │ ...

  6. Java遍历文件目录

    函数介绍 File[] listFiles():返回当前文件的子目录或子文件的文件数组. 遍历目录 调用listFiles()即可得文件的子目录和子文件,如果存在子目录,那么子目录需要再次调用list ...

  7. BUNOJ 1011

    字符串处理的题.原题链接 AC代码: #include<cstring> #include<cstdio> #include<string> #include< ...

  8. react+react-router+react-redux+nodejs+mongodb项目

    一个实际项目(OA系统)中的部分功能.这个demo中引入了数据库,数据库使用了mongodb.安装mongodb才能运行完整的功能.要看完整的项目可以移步我的github 技术栈 React v15. ...

  9. jstree树形菜单

    final 用于声明属性.方法和类,分别表示属性不可变,方法不可重写,类不可继承.其实可以参考用easyui的tree 和 ztree参考: https://www.jstree.com/demo/ ...

  10. 修改或隐藏Nginx的版本号

    隐藏版本号 隐藏nginx的版本号很简单,nginx的HttpCoreModule提供了一条叫做server_tokens指令,我这要将这条指令设置为“server_tokens off”就可以了. ...