与二叉树有关的编程题的Java代码实现
该文章几乎包含了所有与二叉树相关的基础面试题,其中包括二叉树的四种遍历方法:前序遍历,中序遍历,后续遍历,层次遍历。
算法题包括:
二叉树的序列化和反序列化
给定一颗二叉搜索树,请找出其中的第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代码实现的更多相关文章
- 去哪儿网2017校招在线笔试(前端工程师)编程题及JavaScript代码
编程题很简单.整个试卷结构为: 一.问答题: 对前端的理解,了解哪些框架库? 二.在线编程题:身份证分组 如下第一道:身份证分组 三.在线编程题:身份证分组.统计字符.酒店价格(三选二) 如下第二三四 ...
- hdu-5670 Machine(水题附上java代码)
题目链接: Machine Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) 问题描 ...
- 剑指Offer编程题(Java实现)——链表中环的入口结点
题目描述 给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null. 思路一 迭代遍历链表,利用HashSet将每个结点添加到哈希表中,如果添加失败(重复遍历了这个结点即遇到环),输出 ...
- 剑指Offer编程题(Java实现)——删除链表中重复的结点
题目描述 在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针. 例如,链表1->2->3->3->4->4->5 处理后 ...
- 剑指Offer编程题(Java实现)——复杂链表的复制
题目描述 输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head.(注意,输出结果中请不要返回参数中的节点引用,否 ...
- 剑指Offer编程题(Java实现)——链表中倒数第k个结点
题目描述 输入一个链表,输出该链表中倒数第k个结点. 注意: 该题目不可以用先反转链表再输出第k个结点的方式,因为反转链表会改变该结点的next指向 思路一 使用栈Stack倒序存储,顺序pop第k个 ...
- 剑指Offer编程题(Java实现)——从尾到头打印链表
题目描述 输入一个链表,按链表值从尾到头的顺序返回一个ArrayList. 解题思路 思路一:使用头插法 使用头插法可以得到一个逆序的链表.遍历链表,每次将所遍历节点插入到链表的头部. 头结点和第一个 ...
- 剑指Offer编程题(Java实现)——数组中的重复数字
题目描述 在一个长度为n的数组里的所有数字都在0到n-1的范围内. 数组中某些数字是重复的,但不知道有几个数字是重复的.也不知道每个数字重复几次.请找出数组中任意一个重复的数字. 例如,如果输入长度为 ...
- 剑指Offer编程题(Java实现)——两个链表的第一个公共结点
题目描述: 输入两个链表,找出它们的第一个公共结点. 思路一: 设 A 的长度为 a + c,B 的长度为 b + c,其中 c 为尾部公共部分长度,可知 a + c + b = b + c + a. ...
随机推荐
- .NET Core阿里大于短信发送SDK修改以及使用
一.问题背景 继上次七牛云SDK的问题之后(参考:http://www.cnblogs.com/OMango/p/8447480.html),在发送短信的功能上又出现了问题,我们短信服务使用的是阿里大 ...
- PHP页面间的参数传递
我们定义page01.php和page02.php两个php文件,将page01中的内容想办法传递到page02,然后供我们继续使用.--------------------------------- ...
- 用Open SSH生成公钥和私钥(Win)
也可以使用 dsa 加密算法进行加密,命令如下: ssh-keygen -t dsa
- UVA - 1631 Locker 记忆化搜索
题意:给定两个密码串,每次可以让1~3个相邻的密码向上或者向下滚动,每个密码是 ,问最少需要多少次滚动可以让原串成为目标串? 思路:假设当前要让第i位密码还原,我们可以同时转动,不同的转动方式会影响后 ...
- 通讯服务类API调用的代码示例合集:短信服务、手机号归属地查询、电信基站查询等
以下示例代码适用于 www.apishop.net 网站下的API,使用本文提及的接口调用代码示例前,您需要先申请相应的API服务. 短信服务:通知类和验证码短信,全国三网合一通道,5秒内到达,费用低 ...
- C语言老司机学Python (二)
标准数据类型: 共6种:Number(数字),String(字符串),List(列表),Tuple(元组),Sets(集合),Dictionary(字典) 本次学习主要是和数据类型混个脸熟,知道每样东 ...
- Go基础之--操作Mysql(二)
在上一篇文章中主要整理了Golang连接mysql以及一些基本的操作,并进行了大概介绍,这篇文章对增删查改进行详细的整理 读取数据 在上一篇文章中整理查询数据的时候,使用了Query的方法查询,其实d ...
- 修改或隐藏Nginx的版本号
隐藏版本号 隐藏nginx的版本号很简单,nginx的HttpCoreModule提供了一条叫做server_tokens指令,我这要将这条指令设置为“server_tokens off”就可以了. ...
- 超链接a标签的属性target的可选值有哪些以及区别
超链接a标签的属性target的可选值有哪些以及区别 1.<a target="_blank"></a> 2.<a target="_par ...
- C#技术点--修改系统时间
C#的System.DateTime类提供了对日期时间的封装,用它进行时间的转换和处理很方便,但是我没有在其中找到任何可以用来修改系统时间的成员.用过VC.VB等的朋友可能知道,我们可以调用Win32 ...