为什么需要树这种数据结构
1)数组存储方式的分析优点:
通过下标方式访问元素,速度快。对于有序数组,还可使用二分查找提高检索速度。
缺点:如果要检索具体某个值,或者插入值(按一定顺序)会整体移动,效率较低
2)链式存储方式的分析优点:
在一定程度上对数组存储方式有优化(比如:插入一个数值节点,只需要将插入节点,
链接到链表中即可, 删除效率也很好)。缺点:在进行检索时,效率仍然较低,比
如(检索某个值,需要从头节点开始遍历)
3)树存储方式的分析:
能提高数据存储,读取的效率, 比如利用 二叉排序树(Binary Sort Tree),既可以保
证数据的检索速度,同时也可以保证数据的插入,删除,修改的速度.
案例: [7, 3, 10, 1, 5, 9, 12]
二叉树:每个节点只能有两个子节点:左节点,右节点
二叉树的实现
节点类
package treeStructrue;
/**
* 英雄节点
*/
public class HeroNode {
/**
* 英雄名字
*/
private String name;
/**
* 英雄id
*/
private int id;
/**
* 英雄左节点
*/
private HeroNode left;
/**
* 英雄右节点
*/
private HeroNode right;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public HeroNode getLeft() {
return left;
}
public void setLeft(HeroNode left) {
this.left = left;
}
public HeroNode getRight() {
return right;
}
public void setRight(HeroNode right) {
this.right = right;
}
public HeroNode(int id, String name) {
this.name = name;
this.id = id;
}
@Override
public String toString() {
return "HeroNode{" +
"name='" + name + '\'' +
", id=" + id +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
HeroNode heroNode = (HeroNode) o;
return id == heroNode.id;
}
@Override
public int hashCode() {
return id;
}
/**
* 前序遍历
*/
public void previousOrder(){
System.out.println(this);
if(this.getLeft() != null){
this.getLeft().previousOrder();
}
if(this.getRight() != null){
this.getRight().previousOrder();
}
}
/**
* 中序遍历
*/
public void infixOrder(){
if(this.getLeft() != null){
this.getLeft().infixOrder();
}
System.out.println(this);
if(this.getRight() != null){
this.getRight().infixOrder();
}
}
/**
* 后序遍历
*/
public void postOrder(){
if(this.getLeft() != null){
this.getLeft().postOrder();
}
if(this.getRight() != null){
this.getRight().postOrder();
}
System.out.println(this);
}
/**
* 根据id前序查找节点
* @param id
* @return
*/
public HeroNode previousOrderSearch(int id){
if(this.getId() == id){
return this;
}
HeroNode temp = null;
if(getLeft() != null){
temp = getLeft().previousOrderSearch(id);
}
if(temp != null){
return temp;
}
if(getRight() != null){
temp = getRight().previousOrderSearch(id);
}
return temp;
}
/**
* 根据id中序查找节点
* @param id
* @return
*/
public HeroNode infixOrderSearch(int id){
HeroNode temp = null;
if(getLeft() != null){
temp = getLeft().previousOrderSearch(id);
}
if(temp != null){
return temp;
}
if(this.getId() == id){
return this;
}
if(getRight() != null){
temp = getRight().previousOrderSearch(id);
}
return temp;
}
/**
* 根据id后序查找节点
* @param id
* @return
*/
public HeroNode postOrderSearch(int id){
HeroNode temp = null;
if(getLeft() != null){
temp = getLeft().previousOrderSearch(id);
}
if(temp != null){
return temp;
}
if(getRight() != null){
temp = getRight().previousOrderSearch(id);
}
if(temp != null){
return temp;
}
if(this.getId() == id){
return this;
}
return temp;
}
/**
* 根据id删除
* @param id
*/
public void delete(int id){
//先判断左节点是否为要删除的节点
if(this.getLeft().getId() == id){
this.setLeft(null) ;
return ;
}
//再判断右节点是否为要删除的节点
if(this.getRight().getId() == id){
this.setRight(null);
return ;
}
//向左遍历
if(this.getLeft() != null){
this.getLeft().delete(id);
}
//向右遍历
if(this.getRight() != null){
this.getRight().delete(id);
}
}
}
树类
package treeStructrue;
/**
* 树的类
*/
public class HeroTree {
/**
* 根节点
*/
private HeroNode root;
public HeroNode getRoot() {
return root;
}
public void setRoot(HeroNode root) {
this.root = root;
}
/**
* 前序遍历
*/
public void previousOrder(){
if(root != null){
root.previousOrder();
}else{
System.out.println("二叉树为空");
}
}
/**
* 中序遍历
*/
public void infixOrder(){
if(root != null){
root.infixOrder();
}else{
System.out.println("二叉树为空");
}
}
/**
* 后序遍历
*/
public void postOrder(){
if(root != null){
root.postOrder();
}else{
System.out.println("二叉树为空");
}
}
/**
* 前序查找
* @param id
* @return
*/
public HeroNode previousOrderSearch(int id){
if(root != null){
return root.previousOrderSearch(id);
}else{
return null;
}
}
/**
* 中序查找
* @param id
* @return
*/
public HeroNode infixOrderSearch(int id){
if(root != null){
return root.infixOrderSearch(id);
}else{
return null;
}
}
/**
* 后序查找
* @param id
* @return
*/
public HeroNode postOrderSearch(int id){
if(root != null){
return root.postOrderSearch(id);
}else{
return null;
}
}
/**
* 根据id删除
* @param id
*/
public void delete(int id){
if(root != null){
root.delete(id);
}else{
System.out.println("二叉树为空,无法删除");
}
}
/**
* 返回以它为根节点的树的高度
* @param root
* @return
*/
private int height(HeroNode root){
int leftHeight = 0;
int rightHeight = 0;
if(root == null){
return 0;
}
leftHeight = height(root.getLeft());
rightHeight = height(root.getRight());
return leftHeight > rightHeight?leftHeight + 1:rightHeight + 1;
}
/**
* 得到树的高度
* @return
*/
public int height(){
return height(root);
}
}
测试类
package treeStructrue;
/**
* 测试树结构
*/
public class Client {
public static void main(String[] args) {
HeroNode root = new HeroNode(0, "root");
HeroNode h1 = new HeroNode(1, "hero1");
HeroNode h2 = new HeroNode(2, "hero2");
HeroNode h3 = new HeroNode(3, "hero3");
HeroNode h4 = new HeroNode(4, "hero4");
HeroNode h5 = new HeroNode(5, "hero5");
HeroTree tree = new HeroTree();
tree.setRoot(root);
root.setLeft(h1);
root.setRight(h2);
h1.setLeft(h3);
h3.setRight(h4);
h2.setLeft(h5);
tree.postOrder();
}
}
结果:没有问题