二叉树的Java实现及特点总结

转载请注明出处:http://blog.csdn.net/zhaokaiqiang1992

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

    

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

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

    完全二叉树:若设二叉树的高度为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基本数据类型作为节点的数据,如果要使用节点带有更加复杂的数据类型,换成对应的对象即可。

[java] view
plain
copy

  1. /** 
  2.  *  
  3.  * @ClassName: com.tree.TreeNode 
  4.  * @Description: 节点 
  5.  * @author zhaokaiqiang 
  6.  * @date 2014-12-5 下午4:43:24 
  7.  *  
  8.  */  
  9. public class TreeNode {  
  10.   
  11.     // 左节点  
  12.     private TreeNode lefTreeNode;  
  13.     // 右节点  
  14.     private TreeNode rightNode;  
  15.     // 数据  
  16.     private int value;  
  17.   
  18.     private boolean isDelete;  
  19.   
  20.     public TreeNode getLefTreeNode() {  
  21.         return lefTreeNode;  
  22.     }  
  23.   
  24.     public void setLefTreeNode(TreeNode lefTreeNode) {  
  25.         this.lefTreeNode = lefTreeNode;  
  26.     }  
  27.   
  28.     public TreeNode getRightNode() {  
  29.         return rightNode;  
  30.     }  
  31.   
  32.     public void setRightNode(TreeNode rightNode) {  
  33.         this.rightNode = rightNode;  
  34.     }  
  35.   
  36.     public int getValue() {  
  37.         return value;  
  38.     }  
  39.   
  40.     public void setValue(int value) {  
  41.         this.value = value;  
  42.     }  
  43.   
  44.     public boolean isDelete() {  
  45.         return isDelete;  
  46.     }  
  47.   
  48.     public void setDelete(boolean isDelete) {  
  49.         this.isDelete = isDelete;  
  50.     }  
  51.   
  52.     public TreeNode() {  
  53.         super();  
  54.     }  
  55.   
  56.     public TreeNode(int value) {  
  57.         this(null, null, value, false);  
  58.     }  
  59.   
  60.     public TreeNode(TreeNode lefTreeNode, TreeNode rightNode, int value,  
  61.             boolean isDelete) {  
  62.         super();  
  63.         this.lefTreeNode = lefTreeNode;  
  64.         this.rightNode = rightNode;  
  65.         this.value = value;  
  66.         this.isDelete = isDelete;  
  67.     }  
  68.   
  69.     @Override  
  70.     public String toString() {  
  71.         return "TreeNode [lefTreeNode=" + lefTreeNode + ", rightNode="  
  72.                 + rightNode + ", value=" + value + ", isDelete=" + isDelete  
  73.                 + "]";  
  74.     }  
  75.   
  76. }  

    下面给出二叉树的代码实现。由于在二叉树中进行节点的删除非常繁琐,因此,下面的代码使用的是利用节点的isDelete字段对节点的状态进行标识

[java] view
plain
copy

  1. /** 
  2.  *  
  3.  * @ClassName: com.tree.Tree 
  4.  * @Description: 二叉树的定义 
  5.  * @author zhaokaiqiang 
  6.  * @date 2014-12-8 上午7:51:49 
  7.  *  
  8.  */  
  9.   
  10. public class BinaryTree {  
  11.   
  12.     // 根节点  
  13.     private TreeNode root;  
  14.   
  15.     public TreeNode getRoot() {  
  16.         return root;  
  17.     }  
  18.   
  19.     /** 
  20.      * 插入操作 
  21.      *  
  22.      * @param value 
  23.      */  
  24.     public void insert(int value) {  
  25.   
  26.         TreeNode newNode = new TreeNode(value);  
  27.   
  28.         if (root == null) {  
  29.             root = newNode;  
  30.             root.setLefTreeNode(null);  
  31.             root.setRightNode(null);  
  32.         } else {  
  33.   
  34.             TreeNode currentNode = root;  
  35.             TreeNode parentNode;  
  36.   
  37.             while (true) {  
  38.   
  39.                 parentNode = currentNode;  
  40.                 // 往右放  
  41.                 if (newNode.getValue() > currentNode.getValue()) {  
  42.                     currentNode = currentNode.getRightNode();  
  43.                     if (currentNode == null) {  
  44.                         parentNode.setRightNode(newNode);  
  45.                         return;  
  46.                     }  
  47.                 } else {  
  48.                     // 往左放  
  49.                     currentNode = currentNode.getLefTreeNode();  
  50.                     if (currentNode == null) {  
  51.                         parentNode.setLefTreeNode(newNode);  
  52.                         return;  
  53.                     }  
  54.   
  55.                 }  
  56.             }  
  57.         }  
  58.     }  
  59.   
  60.     /** 
  61.      * 查找 
  62.      *  
  63.      * @param key 
  64.      * @return 
  65.      */  
  66.     public TreeNode find(int key) {  
  67.   
  68.         TreeNode currentNode = root;  
  69.   
  70.         if (currentNode != null) {  
  71.   
  72.             while (currentNode.getValue() != key) {  
  73.   
  74.                 if (currentNode.getValue() > key) {  
  75.                     currentNode = currentNode.getLefTreeNode();  
  76.                 } else {  
  77.                     currentNode = currentNode.getRightNode();  
  78.                 }  
  79.   
  80.                 if (currentNode == null) {  
  81.                     return null;  
  82.                 }  
  83.   
  84.             }  
  85.   
  86.             if (currentNode.isDelete()) {  
  87.                 return null;  
  88.             } else {  
  89.                 return currentNode;  
  90.             }  
  91.   
  92.         } else {  
  93.             return null;  
  94.         }  
  95.   
  96.     }  
  97.   
  98.     /** 
  99.      * 中序遍历 
  100.      *  
  101.      * @param treeNode 
  102.      */  
  103.     public void inOrder(TreeNode treeNode) {  
  104.         if (treeNode != null && treeNode.isDelete() == false) {  
  105.             inOrder(treeNode.getLefTreeNode());  
  106.             System.out.println("--" + treeNode.getValue());  
  107.             inOrder(treeNode.getRightNode());  
  108.         }  
  109.     }  
  110.   
  111. }  

    在上面对二叉树的遍历操作中,使用的是中序遍历,这样遍历出来的数据是增序的。

    下面是测试代码:

[java] view
plain
copy

  1. public class Main {  
  2.   
  3.     public static void main(String[] args) {  
  4.   
  5.         BinaryTree tree = new BinaryTree();  
  6.         // 添加数据测试  
  7.         tree.insert(10);  
  8.         tree.insert(40);  
  9.         tree.insert(20);  
  10.         tree.insert(3);  
  11.         tree.insert(49);  
  12.         tree.insert(13);  
  13.         tree.insert(123);  
  14.   
  15.         System.out.println("root=" + tree.getRoot().getValue());  
  16.         // 排序测试  
  17.         tree.inOrder(tree.getRoot());  
  18.         // 查找测试  
  19.         if (tree.find(10) != null) {  
  20.             System.out.println("找到了");  
  21.         } else {  
  22.             System.out.println("没找到");  
  23.         }  
  24.         // 删除测试  
  25.         tree.find(40).setDelete(true);  
  26.   
  27.         if (tree.find(40) != null) {  
  28.             System.out.println("找到了");  
  29.         } else {  
  30.             System.out.println("没找到");  
  31.         }  
  32.   
  33.     }  
  34.   
  35. }  
时间: 2024-09-23 20:01:57

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

JAVA 实现二叉树(链式存储结构)_java

二叉树的分类(按存储结构) 树的分类(按存储结构)              顺序存储(用数组表示(静态二叉树))   链式存储 一些特别的二叉根:                                    完全二叉树,平衡二叉树(AVL),线索二叉树,三叉的(带父亲的指针)    二叉搜索树或者叫二叉 查找树(BST)  所用二叉树如下图所示:   二叉树的Java实现(链式存储结构) class TreeNode { private int key = 0; private St

浅谈关于java程序员面试的一些事项

本篇博文针对的是应届毕业生以及工作两三年左右的java程序员. 为什么要跳槽? 这是一个很广义的问题,每个人心中都有一份答案. 例如: 公司的待遇不好, 薪资涨幅不符合预期要求, 厌倦了出差的荒无天日的繁重工作, 公司的妹子太少, 领导太傲娇, 同事之间关系太逼格, 某某同学跳槽到某某公司之后涨到了多少多少钱, 某某同学的朋友的同事的三姑妈家的大儿子的好基友在某某高就, 等等辞职理由. 咱们就不多说了,还是谈谈怎么应付面试吧. 以下内容是我在面试中总结的一些经验,希望这些可以给各位带来帮助和启迪

在JAVA中实现的二叉树结构

最近研究了一下二叉树结构,参考了一些资料,总结了一下. package com.test;/** *//** * * 在JAVA中实现二叉树结构 * * 讲解: * 二个方法函数,一个寻找关键字--searchkey 另一个是插入一个结点:insertTree * * 另外这是一个完全的先序遍历二叉树的语法.先根结点,再左结点,如无再右结点,如些加归至 * * 搜索完毕. * */public class BinaryTreeTest ...{ private BinaryTree root =

遍历-关于利用java建立四则运算的二叉树

问题描述 关于利用java建立四则运算的二叉树 把如图所示的算式生成图右形式的二叉树 简单来说应该就是利用二叉树表达四则运算 中根遍历的结果就是中缀表达式 先根遍历就是前缀表达式 后根遍历就是后缀表达式 解决方案 后缀是最简单的,遇到数字放入堆栈,遇到运算符,弹出最后两个操作数构造表达式,再把表达式入堆栈.

java语言 二叉树(三叉链表存储结构)的深拷贝

问题描述 java语言 二叉树(三叉链表存储结构)的深拷贝 爆炸,这个非递归好复杂,规定不使用栈的非递归,递归都会,非递归就蒙了,有大神能挑战一下吗,急 解决方案 二叉树是一种特殊的数据结构,我们可以对它线性化,方法是,0表示根节点,1 2表示它的子节点,3 4 5 6表示1 2的子节点7 8 9 10 11 12 13 14是再下层-- 很明显,知道一个节点,它的子节点的索引值就是x2+1和x2+2,它的父节点就是-1再整除2. 有了这个知识点,就可以用数组来表示二叉树,也就不用递归和堆栈了.

java创建递归二叉树,输出根数据时出现空指针异常

问题描述 java创建递归二叉树,输出根数据时出现空指针异常 代码如下:import java.io.File;import java.io.FileNotFoundException;import java.util.LinkedList;import java.util.Scanner;import java.util.*;class BiNode{ public String data; public BiNode lchild; public BiNode rchild; public

图解红黑树及Java进行红黑二叉树遍历的方法_java

红黑树红黑树是一种数据结构与算法课堂上常常提到但又不会细讲的树,也是技术面试中经常被问到的树,然而无论是书上还是网上的资料,通常都比较刻板难以理解,能不能一种比较直观的方式来理解红黑树呢?本文将以图形的方式来解释红黑树的插入与删除操作. 对树结构的学习是一个递进的过程,我们通常所接触的树都是二叉树,二叉树简单来说就是每个非叶子节点都有且只有两个孩子,分别叫做左孩子和右孩子.二叉树中有一类特殊的树叫二叉查找树,二叉查找树是一种有序的树,对于每个非叶子节点,其左子树的值都小于它,其右子树的值都大于它

Java实现表达式二叉树_java

什么是二叉树,这里不再介绍,可以自行百度:二叉树.在这里利用java实现"表达式二叉树".  表达式二叉树的定义  第一步先要搞懂表达式二叉树是个什么东东?举个栗子,表达式:(a+b×(c-d))-e/f.将数字放在叶子节点,将操作符放在分支节点,就构成了一个二叉树,由于存储的是一个表达式,称之为"表达式二叉树". 童靴们可能好奇这个到底是怎么构建的?就拿45+23*56/2-5来说吧.首先取出第一个数字45放在叶子节点,遇到"+"后将其放到分支

java二叉树模板抽象化

问题描述 java二叉树模板抽象化 我有两个二叉树类,分别管理着不同的数据 class bt1{ //自身业务逻辑 String s; public String getS(){ return "godness " + s; } //二叉树逻辑 bt1 left; bt1 right; bt1 parent; public void setLeft(bt1 l){ this.left = l; l.parent = this; } public bt1 getLeft(){ retur