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

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

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

完全二叉树:若设二叉树的高度为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二叉树的实现与特点的更多相关文章

  1. java二叉树的实现和遍历

    /* * Java实现二叉树 */ public class BinaryTree { int treeNode; BinaryTree leftTree; BinaryTree rightTree; ...

  2. Java - 二叉树递归与非递归

    树的定义具有递归特性,因此用递归来遍历比较符合特性,但是用非递归方式就比较麻烦,主要是递归和栈的转换. import java.util.Stack; /** * @author 李文浩 * @ver ...

  3. Java二叉树实现及递归与非递归遍历实现

    树的遍历分两种:1.深度优先遍历 1.1 递归算法实现 2.2 非递归算法实现(使用栈存储)2.广度优先遍历(使用队列存储) import java.util.*; /** * 类功能描述: 二叉树遍 ...

  4. java二叉树排序实现

    原创:转载请注明出处 目的:想用java实现二叉树排序算法 思想:利用java中面向对象的思想,即: Tree:类 树根Tree:root //static所属于每一个Tree 左节点Tree:lef ...

  5. java 二叉树遍历

    package com.lever; import java.util.LinkedList;import java.util.Queue; /** * 二叉树遍历 * @author lckxxy ...

  6. 毕业了-java二叉树层次遍历算法

    /*************************************** * 时间:2017年6月23日 * author:lcy * 内容:二叉树的层次遍历 * 需要借助队列这个数据结构,直 ...

  7. JAVA二叉树递归构造、二叉树普通遍历及递归遍历

    二叉树类: package com.antis.tree; public class BinaryTree { int data; //根节点数据 BinaryTree left; //左子树 Bin ...

  8. java 二叉树的创建 遍历

    本来说复习一下BFS和DFS,辗转就来到了二叉树...本文包括二叉树的创建和遍历 概念 数据:1 2 3 4 5 6 7生成一颗二叉树 上面的数是数据,不是位置,要区别一下数据和位置 红色的代表位置, ...

  9. java——二叉树面试题

    import java.util.ArrayList; import java.util.Iterator; import java.util.LinkedList; import java.util ...

随机推荐

  1. 使用 Topshelf 结合 Quartz.NET 创建 Windows 服务

    Ø  前言 之前一篇文章已经介绍了,如何使用 Topshelf 创建 Windows 服务.当时提到还缺少一个任务调度框架,就是 Quartz.NET.而本文就展开对 Quartz.NET 的研究,以 ...

  2. 对xml进行数据查询时发生NoClassDefFoundError,dom4j和jaxen

    xml可扩展标记语言,标准通用标记语言的子集,是一种用于标记电子文件使其具有结构性的标记语言. 在web中,今天我本想测试一下用xml做为数据库存储用户信息,但是在查询用户信息的时候一直发生: jav ...

  3. IDAPython教程(二)

    继续我们的主题—使用IDAPython 让逆向工程师的生活变得更美好. 这一部分,我们将着手处理一个非常常见的问题:shellcode和恶意软件使用hash算法混淆加载的函数和链接库,这项技术被广泛使 ...

  4. luogu 1314 聪明的质检员

    二分答案的边界问题还是要注意 double挨着,int+1-1, 此题用到long long,所以初始化ans要足够大,前缀和优化 依然根据check答案大小左右mid,虽然有s,但是有了+1-1加持 ...

  5. luogu 1268 树的重量

    打眼一看就是最小生成树嘛,但经过板子wa掉的经历后得知,,emmmm,原来是, 构造! (虽然不知是什么但觉得听起来很厉害的样子...手动微笑) n=2的情况 自然就是g(1,2) n=3的情况,由于 ...

  6. flex布局下overflow失效问题

    经常我们会使用flex布局,但是flex布局常常会遇到一些不可思议的麻烦,下面介绍一下overflow遇到的麻烦 我在工作中使用了左右两栏布局 .container { display: flex; ...

  7. LOJ #2547 Luogu P4517「JSOI2018」防御网络

    好像也没那么难写 LOJ #2547 Luogu P4517 题意 在一棵点仙人掌中等概率选择一个点集 求选出点集的斯坦纳树大小的期望 定义点仙人掌为不存在一个点在多个简单环中的连通图 斯坦纳树为在原 ...

  8. 清除redis缓存

    redis-cli -p 6379(指定进入端口号为6379的redis数据库)1.清空当前redis数据库缓存flushdb 2.清空整个redis缓存flushall

  9. 黑客游戏_www.fbisb.com 通关过程

    黑客游戏_www.fbisb.com 首先这个游戏是非常非常基础的. 输入网址 http://www.fbisb.com/youxi/ 来到第一关 ctrl+u查看源码,注意右键不行,因为这段js代码 ...

  10. Pickup Objective Actor

    在角色的头文件中,添加一个布尔变量,设为共有状态,用来判断是否携带目标物体,并暴露给蓝图,类型为仅蓝图可读 UPROPERTY(BlueprintReadOnly,Category="Gam ...