Java上亿数据查找树,Java实现数据结构——二叉查找树

二叉查找树

二叉树是层次结构,要么是空集,要么是一个根(root)的元素和两颗不同的二叉树组成。空树的高度为0,非空树的高度是从根结点到它最远叶子结点的路劲长度+1。

树的遍历

访问树中每个结点一次且只有一次的过程

Tree-example:

0818b9ca8b590ca3270a3433284dd417.png

前序遍历

访问当前结点

访问该结点的左子树

访问该结点的右子树

0818b9ca8b590ca3270a3433284dd417.png

遍历结果:5 3 2 4 7 6 8

用途:打印结构性文档,书、章、节

中序遍历

访问该结点的左子树

访问当前结点

访问该结点的右子树

0818b9ca8b590ca3270a3433284dd417.png

遍历结果:2 3 4 5 6 7 8

用途:以递增的顺序显示二叉树的所有节点

后序遍历

访问该结点的左子树

访问该结点的右子树

访问当前结点

0818b9ca8b590ca3270a3433284dd417.png

遍历结果:2 4 3 6 8 7 5

用途:文件系统中,在找出根目录之前,得到每个文件和子目录。

广度优先遍历

逐层访问树中的结点

1. 访问根结点

2. 从左往右,访问根结点的所有孩子

3. 从左往右,访问根结点的所有孙子结点

遍历结果:5 3 7 2 4 6 8

详细实现

设计结构图:

0818b9ca8b590ca3270a3433284dd417.png

接口定义

package com.edu.chapter.twenty_six.day0416;

import java.util.Iterator;

/** * @author xukai * @date 2017年4月16日 下午6:17:40 * */

public interface Tree> {

public boolean search(E e);

public boolean insert(E e);

public boolean delete(E e);

/** * 先序遍历 */

public void inorder();

/** * 后序遍历 */

public void postorder();

/** * 前序遍历 */

public void preorder();

public int getSize();

public boolean isEmpty();

public Iterator iterator();

}

抽象类定义

package com.edu.chapter.twenty_six.day0416;

import java.util.Iterator;

/** * @author xukai * @param * @date 2017年4月16日 下午6:24:12 * */

public abstract class AbstractTree> implements Tree {

@Override

public void inorder() {

// TODO Auto-generated method stub

}

@Override

public void postorder() {

// TODO Auto-generated method stub

}

@Override

public void preorder() {

// TODO Auto-generated method stub

}

@Override

public boolean isEmpty() {

// TODO Auto-generated method stub

return getSize() == 0;

}

@Override

public Iterator iterator() {

// TODO Auto-generated method stub

return null;

}

}

具体实现

结点静态内部类

/** * 结点类 * @author xukai * @date 2017年4月18日 上午10:52:46 * @param * */

public static class TreeNode>{

E element;

TreeNode left;

TreeNode right;

public TreeNode(E e) {

element = e;

}

@Override

public int hashCode() {

final int prime = 31;

int result = 1;

result =

prime * result + ((element == null) ? 0 : element.hashCode());

result = prime * result + ((left == null) ? 0 : left.hashCode());

result = prime * result + ((right == null) ? 0 : right.hashCode());

return result;

}

@Override

public boolean equals(Object obj) {

if (this == obj)

return true;

if (obj == null)

return false;

if (getClass() != obj.getClass())

return false;

TreeNode> other = (TreeNode>) obj;

if (element == null) {

if (other.element != null)

return false;

} else if (!element.equals(other.element))

return false;

if (left == null) {

if (other.left != null)

return false;

} else if (!left.equals(other.left))

return false;

if (right == null) {

if (other.right != null)

return false;

} else if (!right.equals(other.right))

return false;

return true;

}

@Override

public String toString() {

return "TreeNode [element=" + element + ", left=" + left

+ ", right=" + right + "]";

}

}

添加元素

判断是否为空树

找出当前插入结点的父结点

插入节点,size++

@Override

public boolean insert(E e) {

if (root == null) {

root = createNewNode(e);

} else {

TreeNode parent = null; // 插入元素的父结点

TreeNode current = root;

while (current != null) {

if (e.compareTo(current.element) < 0) {

parent = current;

current = current.left;

} else if (e.compareTo(current.element) > 0) {

parent = current;

current = current.right;

} else {

return false;

}

}

if (e.compareTo(parent.element) < 0) {

parent.left = createNewNode(e);

} else {

parent.right = createNewNode(e);

}

}

size ++;

return true;

}

protected TreeNode createNewNode(E e) {

return new TreeNode(e);

}

查找元素

@Override

public boolean search(E e) {

TreeNode current = root;

while (current != null) {

if (e.compareTo(current.element) < 0) {

current = current.left;

} else if (e.compareTo(current.element) > 0) {

current = current.right;

} else {

return true;

}

}

return false;

}

删除元素

查找到要删除的元素

假如当前结点没有左孩子,将该结点的父结点和当前结点的右孩子相连。

假如当前结点有一个左孩子,找出当前结点current的左子树中最大元素结点rightMax,

将rightMax的父结点和rightMax的左孩子相连,删除rightMax,size–。

@Override

public boolean delete(E e) {

TreeNode parent = null;

TreeNode current = root;

while (current != null) {

if (e.compareTo(current.element) < 0) {

parent = current;

current = current.left;

} else if (e.compareTo(current.element) > 0) {

parent = current;

current = current.right;

} else

break;

}

if (current == null) {

return false;

}

if (current.left == null) {

// current-node not exist left-node

if (parent == null) {

root = current.right;

} else {

// connect to current.right and parent

if (e.compareTo(parent.element) < 0) {

parent.left = current.right;

} else {

parent.right = current.right;

}

}

} else {

// current-node exist left-node

TreeNode parentOfRightMost = current;

TreeNode rightMost = current.left;

while (rightMost.right != null) {

parentOfRightMost = rightMost;

rightMost = rightMost.right;

}

current.element = rightMost.element;

if (parentOfRightMost.right == rightMost) {

parentOfRightMost.right = rightMost.left;

} else {

// parentOfRightMost == current is true;

parentOfRightMost.left = rightMost.left;

}

}

size --;

return true;

}

前序遍历

@Override

public void inorder() {

inorder(root);

}

protected void inorder(TreeNode root) {

if (root == null) return;

inorder(root.left);

System.out.print(root.element + " ");

inorder(root.right);

}

广度优先遍历

/** * 广度优先遍历 */

public void breadthFirstTraversal() {

LinkedList> queue = new LinkedList<>();

if (this.root == null) {

return;

}

queue.add(this.root);

while (!queue.isEmpty()) {

TreeNode node = queue.removeFirst();

System.out.println(node.element + " ");

if (node.left != null) {

queue.add(node.left);

}

if (node.right != null) {

queue.add(node.right);

}

}

}

二叉排序树是一种分层的数据结构。

查看源码(附带Applet可视化界面,乱码是因为项目是utf-8,需要改成gbk)

0818b9ca8b590ca3270a3433284dd417.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值