与二叉树有关的编程题的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. ...
随机推荐
- 注册表命令 regedit32
转自 https://zhidao.baidu.com/question/1958216489744783460.html Regedt32.exe 不支持注册表项文件 (.reg) 的导入和导出. ...
- java-redis初探
一.Redis 简介 Redis 是完全开源免费的,遵守BSD协议,是一个高性能的key-value数据库. Redis 与其他 key - value 缓存产品有以下三个特点: Redis支持数据的 ...
- PHP的性能优化方法总结
什么情况之下,会遇到PHP性能问题? 1:PHP语法使用不恰当. 2:使用PHP语言做了它不擅长的事情. 3:使用PHP语言连接的服务不给力. 4:PHP自身的短板(PHP自身做不了的事情). 5:我 ...
- ContentProvider、ContentResolver、ContentObserver之间的关系
ContentProvider.ContentResolver.ContentObserver之间的关系 ContentPRrovider: * 四大组件的内容提供者,主要用于对外提供数据 * 实现各 ...
- PAT1116. Come on! Let's C (map)
思路:模拟一下就好了,map用来记录每个人的排名. AC代码 #include <stdio.h> #include <map> #include <math.h> ...
- 最实用的Android开发学习路线分享
Android开发学习路线分享.Android发展主导移动互联发展进程,在热门行业来说,Android开发堪称火爆,但是,虽然Android有着自身种种优势,但对开发者的专业性要求也是极高,这种要求随 ...
- ORACLE中修改表的Schema的总结
前阵子遇到一个案例,需要将数据库中的几个表从USER A 移动到USER B下面,在ORACLE中,这个叫做更改表的所有者或者修改表的Schema.其实遇到这种案例,有好几种解决方法.下面我们通过实验 ...
- 获取NVIDIA显卡的温度
NVIDIA显卡在硬件上有温度传感器,可以感知显卡的运行环境.温度数据的获取,一般是通过调用NVIDIA的SDK的相关函数即可.SDK的下载的网址(https://developer.nvidia.c ...
- php session函数
session_start() 开启session 使用session前需要使用该函数 session_id() 获取当前回话的sessionid session_save_path($path) 如 ...
- 从VGA到GPU!细数二十年显卡发展历程
VGA有很多层涵义,本来是用于代表一个分辨率(您可能不了解VGA,但应该知道QVGA代表什么),随后被普遍称为显示输出接口.为了输出VGA分辨 率.提供VGA输出接口,显卡和VGA就有了不解之缘,显卡 ...