Java实现二叉排序(查找)树的操作
2015-05-31 15:22
489 查看
二叉排序树定义:
1.左子树值小于根
2.根的值小于右子树
3.其左右子树又是一颗二叉排序树
抽象数据类型定义,在Java中即是接口的定义
在二叉树的实现中有关于BinaryTreeADT<T>的定义
具体实现如下:
1.左子树值小于根
2.根的值小于右子树
3.其左右子树又是一颗二叉排序树
抽象数据类型定义,在Java中即是接口的定义
/* * 二叉排序树是二叉树的扩展 * 对于二叉树一般不涉及到插入和删除树中的元素,而在二叉查找树中有 * * */ public interface BinarySearchTreeADT<T> extends BinaryTreeADT<T>{ public void addElement(T element) throws NonComparableElementException; public T removeElement(T targetElement) throws ElementNotFoundException; public void removeAllOcurrs(T targetElement); public T removeMin() throws EmptyCollectionException; public T removeMax() throws EmptyCollectionException; public T findMin(); public T findMax(); }
在二叉树的实现中有关于BinaryTreeADT<T>的定义
具体实现如下:
package com.search; import java.util.Iterator; import com.node.BinaryTreeNode; import com.node.ElementNotFoundException; import com.node.LinkedBinaryTree; public class LinkedBinarySearchTree<T> extends LinkedBinaryTree<T> implements BinarySearchTreeADT<T> { public LinkedBinarySearchTree() { super(); } public LinkedBinarySearchTree(T element) throws NonComparableElementException { super(element); if (!(element instanceof Comparable)) throw new NonComparableElementException("LinkedBinarySearchTree!!"); } /** * 在二叉排序树的适当位置添加一个元素 * 1.若树为空:则新添加的元素作为根 * 2.若树不为空:则与根比较 * 若小于,则先判断左子树是否为空,若为空直接将其设置为根的左子树,否则继续与左子树比较 * 若大于,则先判断右子树是否为空,若为空直接将其设置为根的右子树,否则继续与右子树比较 */ @SuppressWarnings("unchecked") @Override public void addElement(T element) throws NonComparableElementException { if (!(element instanceof Comparable)) throw new NonComparableElementException("LinkedBinarySearchTree"); Comparable<T> comparableElement = (Comparable<T>) element; if (isEmpty()) root = new BinaryTreeNode<T>(element); else { if (comparableElement.compareTo(root.getElement()) < 0) { if (root.getLeft() == null) root.setLeft(new BinaryTreeNode<T>(element)); else { addElement(element, root.getLeft()); } } else { if (root.getRight() == null) root.setRight(new BinaryTreeNode<T>(element)); else addElement(element, root.getRight()); } } modCount++; } /** * @param element * @param node */ private void addElement(T element, BinaryTreeNode<T> node) { @SuppressWarnings("unchecked") Comparable<T> comparableElement = (Comparable<T>) element; if (comparableElement.compareTo(node.getElement()) < 0) { if (node.getLeft() == null) node.setLeft(new BinaryTreeNode<T>(element)); else addElement(element, node.getLeft()); } else { if (node.getRight() == null) node.setRight(new BinaryTreeNode<T>(element)); else addElement(element, node.getRight()); } } /** * 删除二叉排序树中的指定元素 * 若删除元素,则必须找到代替的元素,不能破坏二叉排序树的特性 * 有三种情况: * 1.若删除的是叶子节点,则replacement方法直接返回null * 2.若删除的节点只有一个孩子节点,则replacement方法直接返回这个孩子的引用 * 3.若删除的节点有左后孩子,则replacement方法返回中序遍历的后继节点的引用 */ @SuppressWarnings("unchecked") @Override public T removeElement(T targetElement) throws ElementNotFoundException { T result = null; if (isEmpty()) throw new ElementNotFoundException("delete error"); else { BinaryTreeNode<T> parent = null; if (((Comparable<T>) targetElement).equals(root.getElement())) {//删除的元素是根 result = root.getElement(); BinaryTreeNode<T> temp = replacement(root); if (temp == null) root = null; else { root.setElement(temp.getElement()); root.setLeft(temp.getLeft()); root.setRight(temp.getRight()); } modCount--; } else {//删除的元素不是根,则继续查找要删除的元素 parent = root; if (((Comparable<T>) targetElement) .compareTo(root.getElement()) < 0) { result = removeElement(targetElement, root.getLeft(), parent); } else { result = removeElement(targetElement, root.getRight(), parent); } } } return result; } @SuppressWarnings("unchecked") private T removeElement(T targetElement, BinaryTreeNode<T> node, BinaryTreeNode<T> parent) throws ElementNotFoundException { T result = null; if (node == null) throw new ElementNotFoundException("delete error"); else { if (((Comparable<T>) targetElement).equals(node.getElement())) { result = node.getElement(); BinaryTreeNode<T> temp = replacement(node); if (parent.getLeft() == node) parent.setLeft(temp); else parent.setRight(temp); modCount--; } else { parent = node; if (((Comparable<T>) targetElement) .compareTo(node.getElement()) < 0) { removeElement(targetElement, node.getLeft(), parent); } else { removeElement(targetElement, node.getRight(), parent); } } } return result; } private BinaryTreeNode<T> replacement(BinaryTreeNode<T> node) { BinaryTreeNode<T> result = null; if ((node.getLeft() == null) && (node.getRight() == null)) result = null; else if ((node.getLeft() != null) && (node.getRight() == null)) result = node.getLeft(); else if ((node.getLeft() == null) && (node.getRight() != null)) result = node.getRight(); else { BinaryTreeNode<T> parent = node; BinaryTreeNode<T> current = node.getRight(); while (current.getLeft() != null) { parent = current; current = current.getLeft(); } current.setLeft(node.getLeft()); if (node.getRight() != current) { parent.setLeft(current.getRight()); current.setRight(node.getRight()); } result = current; } return result; } @Override public void removeAllOcurrs(T targetElement) { try { removeElement(targetElement); while (contains((T) targetElement)) removeElement(targetElement); } catch (ElementNotFoundException e) { } } /** * 删除二叉排序树的最小值 * 由二叉排序树的特点可知:最小元素位于左子树上,故分为如下三种情况 * 1.当没有左子树时:则最小元素为根,则用右子树替换根 * 2.当删除的最小元素为叶子节点时:直接将其父亲节点的左子树置空 * 3.当删除的最小为树内节点时:直接将其父节点的左孩子指向其右孩子 */ @Override public T removeMin() throws EmptyCollectionException { T result = null ; if(isEmpty()) throw new EmptyCollectionException("LinkedBinarySearchTree"); else{ if(root.getLeft()==null){ result = root.getElement(); root = root.getRight(); }else{ BinaryTreeNode<T> parent = root ; BinaryTreeNode<T> current = root.getLeft(); while(current.getLeft()!=null){ parent = current ; current = current.getLeft(); } result = current.getElement(); parent.setLeft(current.getRight()); } modCount --; } return result; } /** * 删除二叉排序(查找)树中的最大元素 * 由二叉排序树的特性可知,其最大的元素为于右子树上,分为三种情况 * 1.当根只有左子树时:则最大元素为根 * 2.删除的最大元素为叶子节点时:直接将其父节点的右子树置空 * 3.删除的最大元素为树中节点时:父节点的右子树直接指向当前节点的左子树 * @throws EmptyCollectionException */ @Override public T removeMax() throws EmptyCollectionException { T result = null ; if(isEmpty()) throw new EmptyCollectionException("LinkedBinarySearchTree"); else{ if(root.getRight()==null){ result = root.getElement(); root = root.getLeft(); }else{ BinaryTreeNode<T> parent = root ; BinaryTreeNode<T> current = root.getRight(); while(current.getRight()!=null){ parent = current ; current = current.getRight(); } result = current.getElement(); parent.setRight(current.getLeft()); } } return result; } /** *查找二叉排序树的最小元素, *最小元素位于左子树上,一直寻找左子树 */ @Override public T findMin() { T result = null ; BinaryTreeNode<T> current = root; while(current.getLeft()!=null) current = current.getLeft(); result = current.getElement(); return result; } @Override public T findMax() { T result = null ; BinaryTreeNode<T> current = root; while(current.getRight()!=null) current = current.getRight(); result = current.getElement(); return result; } public static void show(Iterator<Integer> iter) { while (iter.hasNext()) { System.out.print(iter.next() + " "); } System.out.println(); } public static void main(String[] args) { try { LinkedBinarySearchTree<Integer> root = new LinkedBinarySearchTree<Integer>(); root.addElement(10); root.addElement(5); root.addElement(15); root.addElement(3); root.addElement(7); root.addElement(13); Iterator<Integer> iter = root.iteratorInOrder(); System.out.println("初始化树为:"); show(iter); // try { // System.out.println(root.removeElement(5)); // } catch (ElementNotFoundException e1) { // // TODO Auto-generated catch block // e1.printStackTrace(); // } // System.out.println("删除5之后:"); // Iterator<Integer> iter1 = root.iteratorInOrder(); // show(iter1); // root.addElement(10); // Iterator<Integer> iter2 = root.iteratorInOrder(); // show(iter2); // // root.removeAllOcurrs(10); // Iterator<Integer> iter3 = root.iteratorInOrder(); // show(iter3); // try { // System.out.println("删除的最小元素为:"+root.removeMin()); // Iterator<Integer> iter4 = root.iteratorInOrder(); // show(iter4); // } catch (EmptyCollectionException e) { // e.printStackTrace(); // } // // try { // System.out.println("删除的最小元素为:"+root.removeMax()); // Iterator<Integer> iter4 = root.iteratorInOrder(); // show(iter4); // } catch (EmptyCollectionException e) { // e.printStackTrace(); // } System.out.println("查找到的最小元素为:"+ root.findMin()); System.out.println("查找到的最大元素为:"+ root.findMax()); } catch (NonComparableElementException e) { e.printStackTrace(); } } }
相关文章推荐
- java学习之集合框架工具类
- 一款工具助你减少java代码bug
- Java反射基础(二)— Class类
- java io操作整理
- java复习(五)
- Dijkstra算法java现实
- JAVA 文档注释,类的说明,HTML说明文档的生成
- 设置MyEclipse的代码自动提示功能
- 个人认为讲解java异常最好的文章
- SpringMVC介绍之Validation
- Spring2.5学习2.3_如何注入基本类型
- Eclipse Luna安装Activiti Designer报错解决方案
- java线程中run和start方法的区别
- java文件读取全了解
- Vijava 学习笔记(指定虚拟机添加虚拟磁盘修订功能版本)
- 牛客网---java工程师综合练习卷(二星级)---练习改错
- Java基础课程
- 02-Myeclipse中SVN的安装
- 开涛的博客:跟我学SpringMVC目录汇总贴、PDF下载、源码下载
- Java_Web之宠物管理系统