与二叉树有关的编程题的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. ...
随机推荐
- java8 - IO
一.学习大纲: 1. 字符编码格式 2. 文件操作(实现文件的增.删.改.查等操作) 3. 目录操作(实现目录的增.删.改.查等操作) 4. 数据传输(实现对文件内容的读.写等操作) 二.关联类: 1 ...
- Flask從入門到入土(四)——登錄實現
表單介紹 1.表單標籤 聲明表單的範圍,位於表單標籤中的元素將被提交 語法: <form> </form> 屬性: Method(提交方式get,post) , Enctyp ...
- 傅里叶变换 - Fourier Transform
傅里叶级数 傅里叶在他的专著<热的解析理论>中提出,任何一个周期函数都可以表示为若干个正弦函数的和,即: \[f(t)=a_0+\sum_{n=1}^{\infty}(a_ncos(n\o ...
- 基础--Redis在Linux环境下的安装
1. 安装redis服务 1.1 检查安装依赖程序 yum install gcc-c++yum install -y tclyum install wget 1.1.1 下载redis安装包 (或者 ...
- tcp/ip 卷一 读书笔记(1)tcp/ip 概述
TCP/IP协议概述 术语 广域网 WAN 局域网 LAN TCP/IP四层网络模型 TCP/IP通常被认为是一个四层协议系统 网络接口层 包括arp,rarp协议,包括操作系统中的网卡驱动程序和对应 ...
- NewLife.XCode 上手指南2018版(一)代码生成
目录 NewLife.XCode 上手指南2018版(一)代码生成 NewLife.XCode 上手指南2018版(二)增 NewLife.XCode 上手指南2018版(三)查 NewLife.XC ...
- java I/O框架 (二)文件操作(File)
1.介绍 java io中最常操作的就是我们电脑中的文件,将这些文件以流的形式本地读写,或者上传到网络上.java中的File类就是对这些存储于磁盘上文件的虚拟映射,这也体现了java面向对象的思想, ...
- SOCKET 编程TCP/IP、UDP
TCP/IP 资源:http://download.csdn.net/detail/mao0514/9061265 server: #include<stdio.h> #include&l ...
- Error Code: 1175. You are using safe update mode and you tried to update a table without a WHERE
1 错误描述 19:15:34 call sp_store_insert(90) Error Code: 1175. You are using safe update mode and you tr ...
- Linux 显示权限
Linux 显示权限 youhaidong@youhaidong-ThinkPad-Edge-E545:~$ ls -lh 总用量 56K -rw-r--r-- 1 youhaidong youhai ...