二叉树是一种非常重要的数据结构,它同时具有数组和链表各自的特点:它可以像数组一样快速查找,也可以像链表一样快速添加。但是他也有自己的缺点:删除操作复杂。

我们先介绍一些关于二叉树的概念名词。

二叉树:是每个结点最多有两个子树的有序树,在使用二叉树的时候,数据并不是随便插入到节点中的,一个节点的左子节点的关键值必须小于此节点,右子节点的关键值必须大于或者是等于此节点,所以又称二叉查找树、二叉排序树、二叉搜索树。

完全二叉树:若设二叉树的高度为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("没找到");
  }

}

}

二叉树的Java实现及特点总结的更多相关文章

  1. 【数据结构】之二叉树的java实现

    转自:http://blog.csdn.net/wuwenxiang91322/article/details/12231657 二叉树的定义: 二叉树是树形结构的一个重要类型.许多实际问题抽象出来的 ...

  2. 数据结构二叉树的java实现,包括二叉树的创建、搜索、删除和遍历

    根据自己的学习体会并参考了一些网上的资料,以java写出了二叉树的创建.搜索.删除和遍历等操作,尚未实现的功能有:根据先序和中序遍历,得到后序遍历以及根据后序和中序遍历,得到先序遍历,以及获取栈的深度 ...

  3. 二分法与二叉树的 Java 实现

    算法与数据结构始终是计算机基础的重要一环,今天我们来讨论下 Java 中二叉树的实现以及一些简单的小算法,如二分查找,归并排序等. 二分查找 二分查找是一种在有序数组中查找某一特定元素的搜索算法,它在 ...

  4. 剑指offer面试题6 重建二叉树(java)

    注:(1)java中树的构建 (2)构建子树时可以直接利用Arrays.copyOfRange(preorder, from, to),这个方法是左开右闭的 package com.xsf.SordF ...

  5. 【数据结构】之二叉树(Java语言描述)

    有关树的一些基础知识点请参考[这篇文章]. 本文主要记录Java语言描述的二叉树相关的一些操作,如创建.遍历等. 首先,我们需要一个表示树中节点的数据结构TreeNode,代码如下: public c ...

  6. 剑指Offer-22.从上往下打印二叉树(C++/Java)

    题目: 从上往下打印出二叉树的每个节点,同层节点从左至右打印. 分析: 按层次打印二叉树的节点,重点就是我们在打印一层节点的时候,同时按顺序保存好当前节点的下一层节点,也就是左节点和右节点,当此层节点 ...

  7. 剑指Offer-4.重建二叉树(C++/Java)

    题目: 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字.例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2 ...

  8. 【LeetCode】101. Symmetric Tree 对称二叉树(Java & Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 DFS BFS 日期 [LeetCode] 题目地址 ...

  9. 轻松搞定面试中的二叉树题目(java&python)

    树是一种比较重要的数据结构,尤其是二叉树.二叉树是一种特殊的树,在二叉树中每个节点最多有两个子节点,一般称为左子节点和右子节点(或左孩子和右孩子),并且二叉树的子树有左右之分,其次序不能任意颠倒.二叉 ...

随机推荐

  1. Ubuntu安装 Alisql编译安装步骤:

    github地址: https://github.com/alibaba/AliSQL 一.直接git下载保存到本地: git clone https://github.com/alibaba/Ali ...

  2. input输入框的光标定位的问题

    input输入框的光标定位的问题 在给input输入框赋值的时候,或者在我之前写模拟下拉框js组件的时候,时不时会碰到光标的小bug问题,比如键盘中的 上移或者下移操作,在浏览器中光标会先移到最前端, ...

  3. Python2.7-SciPy

    SciPy函数库在NumPy库的基础上增加了众多的数学.科学以及工程计算中常用的库函数.例如线性代数.常微分方程数值求解.信号处理.图像处理.稀疏矩阵等等 1.最小二乘拟合 详细介绍:https:// ...

  4. 简单的django配置和命令

    1.创建项目:django-admin startproject 项目名称 2.进入项目:cd 项目名称 3.创建子应用:python manage.py startapp 子应用名称 4.把子应用添 ...

  5. 《MySQL:菜鸟入门系列》

    关于数据库相关知识,几乎是互联网从业者逃不开的一个必备技能,特别是对于DB.开发和测试童鞋来说,更显得重要... 关于MySQL,推荐如下几本书: 入门级:<MySQL必知必会> 进阶级: ...

  6. Android 写一个Activity之间来回跳转的全局工具类(主要是想实现代码的复用)

    废话不多说了,直接上代码,相信大家都能看得懂的. 一.主要工具类 package com.yw.chat.utils; import android.app.Activity; import andr ...

  7. EXCEL2007出错了无法使用文档中的ActiveX 控件

    EXCEL2007出错了无法使用文档中的ActiveX 控件虽说是很久之前的问题,但是正确的解决方法和原因如下!原因:系统update之后出现的问题解决方法:删除C:\Users\[username] ...

  8. ubuntu14.04安装jupyter notebook

    1.使用pip安装Jupyter notebook: pip install jupyter notebook 2.创建Jupyter默认配置文件: jupyter notebook --genera ...

  9. 1.2《想成为黑客,不知道这些命令行可不行》(Learn Enough Command Line to Be Dangerous)——开始第一条命令

    现在开始准备运行我们的第一条命令了,在屏幕上打印'hello'.(字符打印的地方被称为'标准输出',通常指的是屏幕,很少指真的物理打印机设备).这条命令就是echo,这条命令的参数是想要输出的字符串或 ...

  10. 大数据入门第十四天——Hbase详解(一)入门与安装配置

    一.概述 1.什么是Hbase 根据官网:https://hbase.apache.org/ Apache HBase™ is the Hadoop database, a distributed, ...