数据查询
使用二叉树实现数据库存储的意义在于可以快速实现数据检索的定位操作,因为如果使用链表时间复杂度远远高于二叉树的结构,所以对于二叉树最重要的概念就是检索。
由于在二叉树的结构之中需要有排序的需求,那么既然要进行排序处理,那么在整个的实现机制上使用了Compareble的比较器,所以本次的数据检索的查询判断就给予比较器来实现。
- 在IBinaryTree接口中添加数据查询的方法
public boolean (T data); //进行数据查询
- 在IBinaryTreeImpl子类中覆写此方法
/** * 判断数据是否存在 * @param data 要进行判断得数据 * @return 存在返回true,否则返回false */ @Override public boolean contains(T data){ if(data == null){ throw new NullPointerException("存储的二叉树数据是null"); } if(!(data instanceof Comparable)){ //没有实现Comparable接口 throw new ClassCastException("要保存的数据类没有实现Comparable接口"); } if(this.count == 0){ return false; } return this.root.containsNode(data) != null; //返回的结果不为null则表示有数据 }
整体代码+测试:
package 二叉树;
interface IBinaryTree<T>{
public void add(T data); //添加数据的方法
public int size(); //获取数组长度的方法
public Object[] toArray(); //返回所有数据
public boolean contains(T data); //进行数据查询
}
class BinaTreeImpl<T> implements IBinaryTree<T>{
//该内部类只为当前的外部类提供服务
private class Node{
private Comparable<T> data; //要存储的数据,全部进行强制性的转换
private Node left; //左子树
private Node right; //右子数
private Node parent; //父节点
public Node(Comparable<T> data){ //节点创建的同时保存数据
this.data = data;
}
/**
* 添加数据
* @param newNode 要添加的数据对象
*/
public void addNode(Node newNode){
if(newNode.data.compareTo((T) this.data) <= 0){ //如果新节点小于当前对象
if(this.left == null){ //当前左节点为null
this.left = newNode;
this.parent = this; //设置父节点
}else {
this.left.addNode(newNode); //递归调用
}
}
if(newNode.data.compareTo((T) this.data) > 0){ //新节点大于当前对象
if(this.right == null){
this.right = newNode;
this.parent = this; //设置父节点
}else{
this.right.addNode(newNode); //递归调用
}
}
}
/**
* 中序遍历数据并存储全部数据
*/
public void toArrayNode(){
if(this.left != null){ //此时存在左子树
this.left.toArrayNode();
}
BinaTreeImpl.this.resultData[BinaTreeImpl.this.foot++] =(T)this.data; //存储当前数据
if(this.right != null){ //此时存在右子树
this.right.toArrayNode();
}
}
/**
* 遍历节点比较是否存在该数据
* @return 有则返回该节点,没有则返回null
*/
public Node containsNode(T data){
if(this.data.compareTo(data) == 0){ //数据相同
return this; //返回当前节点
}else { //结果不同
if (this.data.compareTo(data) < 0) { //当前对象数据比传入的对象数据小,查询右节点
if (this.right != null) {
return this.right.containsNode(data);
} else {
return null; //此时没有数据匹配
}
}else { //当前对象数据比传入的对象数据大,查询左节点
if (this.left != null) {
return this.left.containsNode(data);
}else {
return null; //此时没有数据匹配
}
}
}
}
}
//----------------以下操作为二叉树结构------------------
private Node root; //根节点
private int count; //数据的个数
private int foot; //控制数组的脚标
private Object[] resultData; //存储数据的对象数组
//添加数据
@Override
public void add(T data) {
if (data == null){ //由于data需要排序,如果为null肯定无法使用
throw new NullPointerException("存储的二叉树数据是null");
}
if(!(data instanceof Comparable)){ //没有实现Comparable接口
throw new ClassCastException("要保存的数据类没有实现Comparable接口");
}
Node newNode = new Node((Comparable<T>) data); // 将数据保存在节点之中
if(root == null){ //当前没有根节点存在
this.root = newNode;
}else{ //有根节点存在,需要确定节点的位置,提交给Node类处理
this.root.addNode(newNode);
}
this.count++; //记录数据个数
}
/**
* 获取数组个数
* @return 数组长度
*/
@Override
public int size(){
return this.count;
}
/**
* 获取全部数据
* @return 存储全部数据的对象数组
*/
@Override
public Object[] toArray(){
if(this.count == 0){
return null;
}
this.foot = 0; //脚标清零
this.resultData = new Object[this.count]; //实例化对象数组
this.root.toArrayNode(); //提交给Node处理
return this.resultData; //返回数组
}
/**
* 判断数据是否存在
* @param data 要进行判断得数据
* @return 存在返回true,否则返回false
*/
@Override
public boolean contains(T data){
if(data == null){
throw new NullPointerException("存储的二叉树数据是null");
}
if(!(data instanceof Comparable)){ //没有实现Comparable接口
throw new ClassCastException("要保存的数据类没有实现Comparable接口");
}
if(this.count == 0){
return false;
}
return this.root.containsNode(data) != null; //返回的结果不为null则表示有数据
}
}
public class BinaryTree类 {
public static void main(String[] args) {
BinaTreeImpl<Integer> tree = new BinaTreeImpl<>();
int numbers[] = new int[]{10,30,50,60,80,90,95};
for (int num : numbers){
tree.add(num);
}
System.out.println("【元素个数】"+tree.size());
for(Object obj:tree.toArray()) {
System.out.print(obj + "、");
}
System.out.println("\n【测试元素1是否存在】:"+tree.contains(1));
System.out.println("【测试元素12是否存在】:"+tree.contains(12));
}
}
【元素个数】7
10、30、50、60、80、90、95、
【测试元素1是否存在】:false
【测试元素12是否存在】:false