java实现二叉树常见操作
package com.xk.test.struct.newp; import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Stack; public class MyBinaryTree { /**
* 插入节点
* @param root
* @param node
* @return
*/
TreeNode insertNode(TreeNode root,TreeNode node){
if(root == node){
return node;
}
TreeNode tmp = new TreeNode();
tmp = root;
TreeNode last = null;
while(tmp!=null){
last = tmp;
if(tmp.val>node.val){
tmp = tmp.left;
}else{
tmp = tmp.right;
}
}
if(last!=null){
if(last.val>node.val){
last.left = node;
}else{
last.right = node;
}
}
return root;
} /**
* 递归解法前序遍历
* @param root
* @return
*/
ArrayList<Integer> preOrderReverse(TreeNode root){
ArrayList<Integer> result = new ArrayList<Integer>();
preOrder2(root,result);
return result; }
void preOrder2(TreeNode root,ArrayList<Integer> result){
if(root == null){
return;
}
result.add(root.val);
preOrder2(root.left,result);
preOrder2(root.right,result);
} /**
* 迭代解法前序遍历
* @param root
* @return
*/
ArrayList<Integer> preOrder(TreeNode root){
Stack<TreeNode> stack = new Stack<TreeNode>();
ArrayList<Integer> list = new ArrayList<Integer>();
if(root == null){
return list;
}
stack.push(root);
while(!stack.empty()){
TreeNode node = stack.pop();
list.add(node.val);
if(node.right!=null){
stack.push(node.right);
}
if(node.left != null){
stack.push(node.left);
} }
return list;
} /**
* 中序遍历
* @param root
* @return
*/
ArrayList<Integer> inOrder(TreeNode root){
ArrayList<Integer> list = new ArrayList<Integer>();
Stack<TreeNode> stack = new Stack<TreeNode>();
TreeNode current = root;
while(current != null|| !stack.empty()){
while(current != null){
stack.add(current);
current = current.left;
}
current = stack.peek();
stack.pop();
list.add(current.val);
current = current.right; }
return list;
} /**
* 后序遍历
* @param root
* @return
*/
ArrayList<Integer> postOrder(TreeNode root){
ArrayList<Integer> list = new ArrayList<Integer>();
if(root == null){
return list;
}
list.addAll(postOrder(root.left));
list.addAll(postOrder(root.right));
list.add(root.val);
return list;
} /**
* 最大深度
* @param node
* @return
*/
int maxDeath(TreeNode node){
if(node==null){
return 0;
}
int left = maxDeath(node.left);
int right = maxDeath(node.right);
return Math.max(left,right) + 1;
} /**
* 层次遍历
* @param root
* @return
*/
ArrayList<ArrayList<Integer>> levelOrder(TreeNode root){
ArrayList<ArrayList<Integer>> result = new ArrayList<ArrayList<Integer>>();
if(root == null){
return result;
}
Queue<TreeNode> queue = new LinkedList<TreeNode>();
queue.offer(root);
while(!queue.isEmpty()){
int size = queue.size();
ArrayList<Integer> level = new ArrayList<Integer>();
for(int i = 0;i < size ;i++){
TreeNode node = queue.poll();
level.add(node.val);
if(node.left != null){
queue.offer(node.left);
}
if(node.right != null){
queue.offer(node.right);
}
}
result.add(level);
}
return result;
} /**
* 最小深度
* @param root
* @return
*/
int getMinDepth(TreeNode root){
if(root == null){
return 0;
}
return getMin(root);
}
int getMin(TreeNode root){
if(root == null){
return Integer.MAX_VALUE;
}
if(root.left == null&&root.right == null){
return 1;
}
return Math.min(getMin(root.left),getMin(root.right)) + 1;
} /**
* 节点的个数
* @param root
* @return
*/
int numOfTreeNode(TreeNode root){
if(root == null){
return 0; }
int left = numOfTreeNode(root.left);
int right = numOfTreeNode(root.right);
return left + right + 1;
} /**
* 叶子节点的个数
* @param root
* @return
*/
int numsOfNodeTreeNode(TreeNode root){
if(root == null){
return 0;
}
if(root.left==null&&root.right==null){
return 1;
}
return numsOfNodeTreeNode(root.left)+numsOfNodeTreeNode(root.right); } /**
* 第k层节点的个数
* @param root
* @param k
* @return
*/
int numsOfkLevelTreeNode(TreeNode root,int k){
if(root == null||k<1){
return 0;
}
if(k==1){
return 1;
}
int numsLeft = numsOfkLevelTreeNode(root.left,k-1);
int numsRight = numsOfkLevelTreeNode(root.right,k-1);
return numsLeft + numsRight;
} /**
* 翻转二叉树or镜像二叉树
* @param root
* @return
*/
TreeNode mirrorTreeNode(TreeNode root){
if(root == null){
return null;
}
TreeNode left = mirrorTreeNode(root.left);
TreeNode right = mirrorTreeNode(root.right);
root.left = right;
root.right = left;
return root;
} /**
* 两个二叉树是否互为镜像
* @param t1
* @param t2
* @return
*/
boolean isMirror(TreeNode t1,TreeNode t2){
if(t1==null&&t2==null){
return true;
}
if(t1==null||t2==null){
return false;
}
if(t1.val != t2.val){
return false;
}
return isMirror(t1.left,t2.right)&&isMirror(t1.right,t2.left);
} /**
* 是否是平衡二叉树
* 它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。
* @param node
* @return
*/
boolean isBalanced(TreeNode node){
return maxDeath2(node)!=-1;
}
int maxDeath2(TreeNode node){
if(node == null){
return 0;
}
int left = maxDeath2(node.left);
int right = maxDeath2(node.right);
if(left==-1||right==-1||Math.abs(left-right)>1){
return -1;
}
return Math.max(left, right) + 1;
} /**
* 是否是完全二叉树
* 对于深度为K的,有n个结点的二叉树,当且仅当其每一个结点都与深度为K的满二叉树中编号从1至n的结点一一对应时称之为完全二叉树。
* @param root
* @return
*/
boolean isCompleteTreeNode(TreeNode root){
if(root == null){
return false;
}
Queue<TreeNode> queue = new LinkedList<TreeNode>();
queue.add(root);
boolean result = true;
boolean hasNoChild = false;
while(!queue.isEmpty()){
TreeNode current = queue.remove();
if(hasNoChild){
if(current.left!=null||current.right!=null){
result = false;
break;
}
}else{
if(current.left!=null&¤t.right!=null){
queue.add(current.left);
queue.add(current.right);
}else if(current.left!=null&¤t.right==null){
queue.add(current.left);
hasNoChild = true; }else if(current.left==null&¤t.right!=null){
result = false;
break;
}else{
hasNoChild = true;
}
} }
return result;
} /**
* 是否是合法的二叉查找树(BST)
一棵BST定义为:
节点的左子树中的值要严格小于该节点的值。
节点的右子树中的值要严格大于该节点的值。
左右子树也必须是二叉查找树。
一个节点的树也是二叉查找树。
*/
public int lastVal = Integer.MAX_VALUE;
public boolean firstNode = true;
public boolean isValidBST(TreeNode root) {
// write your code here
if(root==null){
return true;
}
if(!isValidBST(root.left)){
return false;
}
if(!firstNode&&lastVal >= root.val){
return false;
}
firstNode = false;
lastVal = root.val;
if (!isValidBST(root.right)) {
return false;
}
return true;
} /**
* 把二叉树打印成多行
* @param pRoot
* @return
*/
ArrayList<ArrayList<Integer> > Print(TreeNode pRoot) {
ArrayList<ArrayList<Integer> > res = new ArrayList<ArrayList<Integer> >();
if(pRoot == null)
return res;
ArrayList<Integer> temp = new ArrayList<Integer>();
Queue<TreeNode> layer = new LinkedList<TreeNode>();
layer.offer(pRoot);
int start = 0, end = 1;
while(!layer.isEmpty()){
TreeNode node = layer.poll();
temp.add(node.val);
start ++;
if(node.left != null)
layer.add(node.left);
if(node.right != null)
layer.add(node.right);
if(start == end){
start = 0;
res.add(temp);
temp = new ArrayList<Integer>();
end = layer.size();
}
}
return res;
} /**
* 按之字形顺序打印二叉树
* @param pRoot
* @return
*/
public ArrayList<ArrayList<Integer> > PrintZ(TreeNode pRoot) {
ArrayList<ArrayList<Integer> > res = new ArrayList<ArrayList<Integer> >();
Stack<TreeNode> s1 = new Stack<TreeNode>();
Stack<TreeNode> s2 = new Stack<TreeNode>();
int flag = 1;
if(pRoot == null)
return res;
s2.push(pRoot);
ArrayList<Integer> temp = new ArrayList<Integer>();
while(!s1.isEmpty() || !s2.isEmpty()){
if(flag % 2 != 0){
while(!s2.isEmpty()){
TreeNode node = s2.pop();
temp.add(node.val);
if(node.left != null){
s1.push(node.left);
}
if(node.right != null){
s1.push(node.right);
}
}
}
if(flag % 2 == 0){
while(!s1.isEmpty()){
TreeNode node = s1.pop();
temp.add(node.val);
if(node.right != null){
s2.push(node.right);
}
if(node.left != null){
s2.push(node.left);
}
}
}
res.add(new ArrayList<Integer>(temp));
temp.clear();
flag ++;
}
return res;
} } class TreeNode{
int val;
//左孩子
TreeNode left;
//右孩子
TreeNode right;
}
转自:https://www.jianshu.com/p/0190985635eb
https://www.weiweiblog.cn/printz/
java实现二叉树常见操作的更多相关文章
- Java Script中常见操作
字符串常见操作:obj.length 长度obj.trim() 移除空白obj.trimLeft()obj.trimRight)obj.charAt(n) 返回字符串中的第n个字符obj.concat ...
- JAVA中字符串常见操作
String str1="hello,world";String str2="Hello,World"; 1.字符串的比较:例,System.out.print ...
- [java学习笔记]java语言基础概述之数组的定义&常见操作(遍历、排序、查找)&二维数组
1.数组基础 1.什么是数组: 同一类型数据的集合,就是一个容器. 2.数组的好处: 可以自动为数组中的元素从零开始编号,方便操作这些数据. 3.格式: (一 ...
- java实现单链表常见操作
一.概述: 本文主要总结单链表常见操作的实现,包括链表结点添加.删除:链表正向遍历和反向遍历.链表排序.判断链表是否有环.是否相交.获取某一结点等. 二.概念: 链表: 一种重要的数据结构,HashM ...
- Java实现二叉树的创建和遍历操作(有更新)
博主强烈建议跳过分割线前面的部分,直接看下文更新的那些即可. 最近在学习二叉树的相关知识,一开始真的是毫无头绪.本来学的是C++二叉树,但苦于编译器老是出故障,于是就转用Java来实现二叉树的操作.但 ...
- java string常见操作题
1. 每个基本类型封装类都有将string转换为基本数据类型的方法 对于非常大的数字请使用Long,代码如下 int age = Integer.parseInt("10"); ...
- Java 语言基础之数组常见操作
对数组操作最基本的动作: 存和取 核心思想: 就是对角标的操作 数组常见操作: 1, 遍历 2, 获取最大值和最小值 3, 排序 4, 查找 5, 折半查找 // 1. 遍历 int[] arr = ...
- java学习第05天(数组常见操作、数组中的数组)
(4)数组常见操作 a.遍历取值 class ArrayDemo3 { public static void main(String[] args) { //System.out.println(&q ...
- Java 中最常见的 5 个错误
在编程时,开发者经常会遭遇各式各样莫名错误.近日,Sushil Das 在 Geek On Java上列举了 Java 开发中常见的 5 个错误,与君共「免」. 原文链接:Top 5 Common M ...
随机推荐
- 商学院教授点评亚马逊、苹果、Facebook和谷歌的商业策略:3星|《互联网四大:亚马逊、苹果、脸书和谷歌的隐藏基因》
“ 谷歌依靠时报的内容吸引了数十亿点击量,而时报使用它们的搜索算法来引入流量.但是两者中显然谷歌拥有更大的权力.它如同地主一样统治着互联网的一个关键领域,而时报就相当于那块草地上的佃农.我们的结局从一 ...
- 防止xss攻击的前端的方法
项目当中在进行安全测试的时候,遇到了xss的攻击,要求前端来做个防御,针对于遇到的xss攻击,做个总结 1.xss---存储型xss的攻击 前端只要在接收到后台数据的时候做个特殊字符的过滤,即可抵制攻 ...
- python 函数,模块知识点运用示例
给定验证码长度n,生成随机验证码,验证码由数字.字母组成(参考chr()内置方法) # 给定验证码长度n,生成随机验证码,验证码由数字.字母组成(参考chr()内置方法) # 第33-126号(共94 ...
- 201871010101-陈来弟《面相对象程序设计(java)》第十周学习总结
201871010101-陈来弟<面相对象程序设计(java)>第十周学习总结 实验八异常.断言与日志 实验时间 2019-11-1 1.实验目的与要求 (1) 掌握java异常处理技术: ...
- shell-基础2
条件表达式 文件判断 文件测试操作符 常用文件测试操作符 说明 -d文件,d的全拼为directory 文件存在且为目录则为真,即测试表达式成立 -f文件,f的全拼为file 文件存在且为普通文件则为 ...
- 代码审计-数组返回NULL绕过
<?php $flag = "flag"; if (isset ($_GET['password'])) { if (ereg ("^[a-zA-Z0-9]+$&q ...
- luoguP3455 [POI2007]ZAP-Queries
题意 设\(f(n)=\sum\limits_{i=1}^{a}\sum\limits_{j=1}^{b}[gcd(i,j)==n],F(n)=\sum\limits_{n|d}f(d)\) 发现\( ...
- React组件简单介绍
组件是 React 的核心,因此了解如何利用它们对于创建优秀的设计结构至关重要. 组件之间传递信息方式: 1.(父组件)向(子组件)传递信息 2.(子组件)向(父组件)传递信息 3.没有任何嵌套关系的 ...
- [LeetCode] 95. Unique Binary Search Trees II 独一无二的二叉搜索树之二
Given an integer n, generate all structurally unique BST's (binary search trees) that store values 1 ...
- 运维工程师打怪升级进阶之路 V2.0
在此之前,发布过两个版本: 运维工程师打怪升级之路 V1.0 版本发布 运维工程师打怪升级必经之路 V1.0.1 很多读者伙伴们反应总结的很系统.很全面,无论是0基础初学者,还是有基础的入门者,或者是 ...