Java二叉树的实现与特点
二叉树是一种非常重要的数据结构,它同时具有数组和链表各自的特点:它可以像数组一样快速查找,也可以像链表一样快速添加。但是他也有自己的缺点:删除操作复杂。
我们先介绍一些关于二叉树的概念名词。
二叉树:是每个结点最多有两个子树的有序树,在使用二叉树的时候,数据并不是随便插入到节点中的,一个节点的左子节点的关键值必须小于此节点,右子节点的关键值必须大于或者是等于此节点,所以又称二叉查找树、二叉排序树、二叉搜索树。
完全二叉树:若设二叉树的高度为h,除第 h 层外,其它各层 (1~h-1) 的结点数都达到最大个数,第h层有叶子结点,并且叶子结点都是从左到右依次排布,这就是完全二叉树。
满二叉树——除了叶结点外每一个结点都有左右子叶且叶子结点都处在最底层的二叉树。
深度——二叉树的层数,就是深度。
二叉树的特点总结:
(1)树执行查找、删除、插入的时间复杂度都是O(logN)
(2)遍历二叉树的方法包括前序、中序、后序
(3)非平衡树指的是根的左右两边的子节点的数量不一致
(4) 在非空二叉树中,第i层的结点总数不超过 , i>=1;
(5)深度为h的二叉树最多有个结点(h>=1),最少有h个结点;
(6)对于任意一棵二叉树,如果其叶结点数为N0,而度数为2的结点总数为N2,则N0=N2+1;
二叉树的Java代码实现
首先是树的节点的定义,下面的代码中使用的是最简单的int基本数据类型作为节点的数据,如果要使用节点带有更加复杂的数据类型,换成对应的对象即可。
/**
*
* @ClassName: com.tree.TreeNode
* @Description: 节点
* @author zhaokaiqiang
* @date 2014-12-5 下午4:43:24
*
*/
public class TreeNode {
// 左节点
private TreeNode lefTreeNode;
// 右节点
private TreeNode rightNode;
// 数据
private int value;
private boolean isDelete;
public TreeNode getLefTreeNode() {
return lefTreeNode;
}
public void setLefTreeNode(TreeNode lefTreeNode) {
this.lefTreeNode = lefTreeNode;
}
public TreeNode getRightNode() {
return rightNode;
}
public void setRightNode(TreeNode rightNode) {
this.rightNode = rightNode;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
public boolean isDelete() {
return isDelete;
}
public void setDelete(boolean isDelete) {
this.isDelete = isDelete;
}
public TreeNode() {
super();
}
public TreeNode(int value) {
this(null, null, value, false);
}
public TreeNode(TreeNode lefTreeNode, TreeNode rightNode, int value,
boolean isDelete) {
super();
this.lefTreeNode = lefTreeNode;
this.rightNode = rightNode;
this.value = value;
this.isDelete = isDelete;
}
@Override
public String toString() {
return "TreeNode [lefTreeNode=" + lefTreeNode + ", rightNode="
+ rightNode + ", value=" + value + ", isDelete=" + isDelete
+ "]";
}
}
下面给出二叉树的代码实现。由于在二叉树中进行节点的删除非常繁琐,因此,下面的代码使用的是利用节点的isDelete字段对节点的状态进行标识
/**
*
* @ClassName: com.tree.Tree
* @Description: 二叉树的定义
* @author zhaokaiqiang
* @date 2014-12-8 上午7:51:49
*
*/
public class BinaryTree {
// 根节点
private TreeNode root;
public TreeNode getRoot() {
return root;
}
/**
* 插入操作
*
* @param value
*/
public void insert(int value) {
TreeNode newNode = new TreeNode(value);
if (root == null) {
root = newNode;
root.setLefTreeNode(null);
root.setRightNode(null);
} else {
TreeNode currentNode = root;
TreeNode parentNode;
while (true) {
parentNode = currentNode;
// 往右放
if (newNode.getValue() > currentNode.getValue()) {
currentNode = currentNode.getRightNode();
if (currentNode == null) {
parentNode.setRightNode(newNode);
return;
}
} else {
// 往左放
currentNode = currentNode.getLefTreeNode();
if (currentNode == null) {
parentNode.setLefTreeNode(newNode);
return;
}
}
}
}
}
/**
* 查找
*
* @param key
* @return
*/
public TreeNode find(int key) {
TreeNode currentNode = root;
if (currentNode != null) {
while (currentNode.getValue() != key) {
if (currentNode.getValue() > key) {
currentNode = currentNode.getLefTreeNode();
} else {
currentNode = currentNode.getRightNode();
}
if (currentNode == null) {
return null;
}
}
if (currentNode.isDelete()) {
return null;
} else {
return currentNode;
}
} else {
return null;
}
}
/**
* 中序遍历
*
* @param treeNode
*/
public void inOrder(TreeNode treeNode) {
if (treeNode != null && treeNode.isDelete() == false) {
inOrder(treeNode.getLefTreeNode());
System.out.println("--" + treeNode.getValue());
inOrder(treeNode.getRightNode());
}
}
}
在上面对二叉树的遍历操作中,使用的是中序遍历,这样遍历出来的数据是增序的。
下面是测试代码:
public class Main {
public static void main(String[] args) {
BinaryTree tree = new BinaryTree();
// 添加数据测试
tree.insert(10);
tree.insert(40);
tree.insert(20);
tree.insert(3);
tree.insert(49);
tree.insert(13);
tree.insert(123);
System.out.println("root=" + tree.getRoot().getValue());
// 排序测试
tree.inOrder(tree.getRoot());
// 查找测试
if (tree.find(10) != null) {
System.out.println("找到了");
} else {
System.out.println("没找到");
}
// 删除测试
tree.find(40).setDelete(true);
if (tree.find(40) != null) {
System.out.println("找到了");
} else {
System.out.println("没找到");
}
}
}
文章转载至:https://www.cnblogs.com/lzq198754/p/5857597.html
Java二叉树的实现与特点的更多相关文章
- java二叉树的实现和遍历
/* * Java实现二叉树 */ public class BinaryTree { int treeNode; BinaryTree leftTree; BinaryTree rightTree; ...
- Java - 二叉树递归与非递归
树的定义具有递归特性,因此用递归来遍历比较符合特性,但是用非递归方式就比较麻烦,主要是递归和栈的转换. import java.util.Stack; /** * @author 李文浩 * @ver ...
- Java二叉树实现及递归与非递归遍历实现
树的遍历分两种:1.深度优先遍历 1.1 递归算法实现 2.2 非递归算法实现(使用栈存储)2.广度优先遍历(使用队列存储) import java.util.*; /** * 类功能描述: 二叉树遍 ...
- java二叉树排序实现
原创:转载请注明出处 目的:想用java实现二叉树排序算法 思想:利用java中面向对象的思想,即: Tree:类 树根Tree:root //static所属于每一个Tree 左节点Tree:lef ...
- java 二叉树遍历
package com.lever; import java.util.LinkedList;import java.util.Queue; /** * 二叉树遍历 * @author lckxxy ...
- 毕业了-java二叉树层次遍历算法
/*************************************** * 时间:2017年6月23日 * author:lcy * 内容:二叉树的层次遍历 * 需要借助队列这个数据结构,直 ...
- JAVA二叉树递归构造、二叉树普通遍历及递归遍历
二叉树类: package com.antis.tree; public class BinaryTree { int data; //根节点数据 BinaryTree left; //左子树 Bin ...
- java 二叉树的创建 遍历
本来说复习一下BFS和DFS,辗转就来到了二叉树...本文包括二叉树的创建和遍历 概念 数据:1 2 3 4 5 6 7生成一颗二叉树 上面的数是数据,不是位置,要区别一下数据和位置 红色的代表位置, ...
- java——二叉树面试题
import java.util.ArrayList; import java.util.Iterator; import java.util.LinkedList; import java.util ...
随机推荐
- C++ vector和list的主要用法区别
vector可以直接通过下标访问,list不可以 1.vector ; i < userTypes.size(); i++) { str = userTypes[i].typeName; } 2 ...
- 堵上NFine SubmitForm漏洞
NFine一个隐藏的漏洞(NFine基本上模仿力软的,力软应该也有,不知道新版本改了没),就是任何登录的用户都可以进行权限修改操作.比如所有模块的SumbitForm或者其它弹出窗口上的按钮,本身只有 ...
- 【二】Spring Cloud 入门
官网 版本号: SpringCloud中文网:https://springcloud.cc SpringCloud中文社区:http://springcloud.cn 以下代码就是Maven父子工程, ...
- mysql load_file在数据库注入中使用
load_file函数只有满足两个条件就可以使用: 1.文件权限:chmod a+x pathtofile 2.文件大小: 必须小于max_allowed_packet 例子: select load ...
- Andrew NG 机器学习编程作业2 Octave
问题描述:用逻辑回归根据学生的考试成绩来判断该学生是否可以入学 这里的训练数据(training instance)是学生的两次考试成绩,以及TA是否能够入学的决定(y=0表示成绩不合格,不予录取:y ...
- web api HttpResponseMessage的简单使用
using Lemon.Common; using Lemon.WeChat.Model; using Lemon.WeChat.Services; using Newtonsoft.Json; us ...
- [C++]Linux之文件拷贝在系统调用和C库函数下的效率比较
声明:如需引用或者摘抄本博文源码或者其文章的,请在显著处注明,来源于本博文/作者,以示尊重劳动成果,助力开源精神.也欢迎大家一起探讨,交流,以共同进步- 0.0 题目: 1. 分别利用文件的系统调用r ...
- jQuery插件整理
toastr:Jquery消息提示插件 http://codeseven.github.io/toastr cropperjs:jQuery简单且功能强大的图片剪裁插件 https://www.npm ...
- 【keepalived】CentOS7.0下安装教程
安装前所需环境 keepalived安装之前,需要环境:wget.gcc.pcre.openssl.zlib.popt-devel 1,wget:用于从外网上下载插件 wget安装命令:yum -y ...
- MFC调用libyara遇到的问题
测试结果 如果调用yara非要变成共享DLL的形式,加那么多的DLL,不如直接调用EXE文件.反而依赖vcruntime运行库的DLL会少很多... 调用libyara 调用libraya和C++调用 ...