您的位置:首页 > 编程语言 > Java开发

Java实现二叉排序(查找)树的操作

2015-05-31 15:22 489 查看
二叉排序树定义:

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();
}
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: