package com.huang.test.datastructure;
import java.util.*;
/**
* 二叉搜索树
*/
abstract class BstData<T> {
BstData<T> left;
BstData<T> right;
BstData<T> parent;
private T value;
/**
* 比较,> 0:则本对象的值大于t2, <0:则本对象的值小于t2, =0:则本对象的值等于t2
* @param t2
* @return
*/
public abstract int compare(T t2);
public BstData() {
}
public BstData(T value) {
this.value = value;
}
public T getValue() {
return value;
}
public void setValue(T value) {
this.value = value;
}
}
class BstUtil<T> {
private BstData<T> root = null;
private void addItem(BstData<T> root, BstData<T> data) {
if (root.compare(data.getValue()) > 0) {
if (root.left != null) {
addItem(root.left, data);
} else {
data.parent = root;
root.left = data;
}
} else if (root.compare(data.getValue()) < 0) {
if (root.right != null) {
addItem(root.right, data);
} else {
data.parent = root;
root.right = data;
}
}
}
private BstData<T> findItemMin(BstData<T> item) {
while (item != null && item.left != null) {
item = item.left;
}
return item;
}
public BstData<T> getRoot() {
return root;
}
/**
* 添加值
* @param data
*/
public void add(BstData<T> data) {
if (root == null) {
root = data;
root.parent = null;
} else {
addItem(root, data);
}
}
/**
* 寻找最小值
* @return
*/
public BstData<T> min() {
return findItemMin(root);
}
/**
* 寻找最大值
* @return
*/
public BstData<T> max() {
BstData<T> right = root;
while (right != null && right.right != null) {
right = right.right;
}
return right;
}
/**
* 查找某个值
* @param value
* @return
*/
public BstData<T> find(T value) {
BstData<T> result = null;
BstData<T> item = root;
while (item != null) {
int comp = item.compare(value);
if (comp == 0) {
result = item;
break;
}
if (comp > 0) {
item = item.left;
} else if (comp < 0) {
item = item.right;
}
}
return result;
}
/**
* 删除某个值
* @param value
*/
public void remove(T value) {
BstData<T> findItem = find(value);
if (findItem != null) {
BstData<T> parent = findItem.parent;
if (findItem.left == null && findItem.right == null)//删除的节点没有左右子节点
{
removeNoneChild(parent, findItem);
} else if (findItem.left != null && findItem.right == null)//删除的节点只有左节点
{
removeHasLeftChild(parent, findItem);
} else if (findItem.left == null && findItem.right != null)//删除的节点只有右节点
{
removeHasRightChild(parent, findItem);
} else if (findItem.left != null && findItem.right != null)//删除的节点有左右子节点
{
removeHasTwoChild(parent, findItem);
}
}
}
/**
* 删除的节点有左右两个子节点
* @param findItem
* @return
*/
private void removeHasTwoChild(BstData<T> parent, BstData<T> findItem) {
BstData<T> newChildRoot = getNewRootWhenHasTwoChild(findItem);
if (parent == null) {
root = newChildRoot;
} else {
newChildRoot.parent = parent;
if (parent.left == findItem) {
parent.left = newChildRoot;
} else if (parent.right == findItem) {
parent.right = newChildRoot;
}
}
}
/**
* 获取删除的节点有左右两个子节点后新的替换节点
* @param findItem
* @return
*/
private BstData<T> getNewRootWhenHasTwoChild(BstData<T> findItem) {
BstData<T> rightMin = findItemMin(findItem.right);
if (rightMin == findItem.right) {
rightMin.left = findItem.left;
findItem.left.parent = rightMin;
} else {
if (rightMin.right == null) {
rightMin.parent.left = null;
} else {
rightMin.parent.left = rightMin.right;
rightMin.right.parent = rightMin.parent;
}
rightMin.left = findItem.left;
findItem.left.parent = rightMin;
rightMin.right = findItem.right;
findItem.right.parent = rightMin;
}
return rightMin;
}
/**
* 删除的节点只有右子节点
* @param parent
* @param findItem
*/
private void removeHasRightChild(BstData<T> parent, BstData<T> findItem) {
BstData<T> newChildRoot = findItem.right;
if (parent == null) {
root = newChildRoot;
root.parent = null;
} else {
findItem.right.parent = parent;
if (parent.left == findItem) {
parent.left = newChildRoot;
} else if (parent.right == findItem) {
parent.right = newChildRoot;
}
}
}
/**
* 删除的节点只有左子节点
* @param parent
* @param findItem
*/
private void removeHasLeftChild(BstData<T> parent, BstData<T> findItem) {
BstData<T> newChildRoot = findItem.left;
if (parent == null) {
root = newChildRoot;
root.parent = null;
} else {
findItem.left.parent = parent;
if (parent.left == findItem) {
parent.left = newChildRoot;
} else if (parent.right == findItem) {
parent.right = newChildRoot;
}
}
}
/**
* 删除的节点没有子节点
* @param parent
* @param findItem
*/
private void removeNoneChild(BstData<T> parent, BstData<T> findItem) {
if (parent == null)//删除根节点
{
root = null;
} else if (parent.left == findItem)//删除的节点是其父节点的左节点
{
parent.left = null;
} else if (parent.right == findItem)//删除的节点是其父节点的右节点
{
parent.right = null;
}
}
/**
* 前序遍历
*/
private void preorderItemTraversal(ArrayList<BstData<T>> list, BstData<T> item)
{
if(item != null)
{
list.add(item);
preorderItemTraversal(list, item.left);
preorderItemTraversal(list, item.right);
}
}
/**
* 中序遍历
*/
private void inorderItemTraversal(ArrayList<BstData<T>> list, BstData<T> item)
{
if(item != null)
{
inorderItemTraversal(list, item.left);
list.add(item);
inorderItemTraversal(list, item.right);
}
}
/**
* 后序遍历
*/
private void postorderItemTraversal(ArrayList<BstData<T>> list, BstData<T> item)
{
if(item != null)
{
postorderItemTraversal(list, item.left);
postorderItemTraversal(list, item.right);
list.add(item);
}
}
/**
* 前序遍历
*/
public ArrayList<BstData<T>> preorderTraversal()
{
ArrayList<BstData<T>> list = new ArrayList<>();
preorderItemTraversal(list, root);
return list;
}
/**
* 中序遍历
*/
public ArrayList<BstData<T>> inorderTraversal()
{
ArrayList<BstData<T>> list = new ArrayList<>();
inorderItemTraversal(list, root);
return list;
}
/**
* 后序遍历
*/
public ArrayList<BstData<T>> postorderTraversal()
{
ArrayList<BstData<T>> list = new ArrayList<>();
postorderItemTraversal(list, root);
return list;
}
/**
* 深度优先遍历
* @return
*/
public ArrayList<BstData<T>> depthFirstTraversal() {
ArrayList<BstData<T>> list = new ArrayList<>();
Stack<BstData<T>> stack = new Stack<>();
stack.push(root);
while (!stack.isEmpty())
{
BstData<T> item = stack.pop();
if(item != null) {
list.add(item);
BstData<T> left = item.left;
BstData<T> right = item.right;
if (right != null)
{
stack.push(right);
}
if(left != null)
{
stack.push(left);
}
}
}
return list;
}
/**
* 广度优先遍历
* @return
*/
public ArrayList<BstData<T>> breathFirstTraversal() {
ArrayList<BstData<T>> list = new ArrayList<>();
LinkedList<BstData<T>> queue = new LinkedList<>();
queue.offer(root);
while(!queue.isEmpty())
{
BstData<T> item = queue.pop();
if(item != null)
{
list.add(item);
BstData<T> left = item.left;
BstData<T> right = item.right;
if(left != null)
{
queue.offer(left);
}
if(right != null)
{
queue.offer(right);
}
}
}
return list;
}
}
class BstIntData extends BstData<Integer> {
public BstIntData() {
}
public BstIntData(Integer intv) {
super(intv);
}
@Override
public int compare(Integer t2) {
return getValue() - t2;
}
@Override
public String toString() {
return "value:" + getValue();
}
}
public class BinarySearchTreeTest {
public static void main(String[] args) {
BstUtil<Integer> bstUtil = new BstUtil<>();
BstIntData intData1 = new BstIntData(100);
BstIntData intData2 = new BstIntData(300);
BstIntData intData3 = new BstIntData(250);
BstIntData intData4 = new BstIntData(350);
BstIntData intData5 = new BstIntData(200);
BstIntData intData6 = new BstIntData(225);
BstIntData intData7 = new BstIntData(215);
BstIntData intData8 = new BstIntData(340);
bstUtil.add(intData1);
bstUtil.add(intData2);
bstUtil.add(intData3);
bstUtil.add(intData4);
bstUtil.add(intData5);
bstUtil.add(intData6);
bstUtil.add(intData7);
bstUtil.add(intData8);
BstData<Integer> root = bstUtil.getRoot();
BstData<Integer> min = bstUtil.min();
BstData<Integer> max = bstUtil.max();
ArrayList<BstData<Integer>> prelist = bstUtil.preorderTraversal();//100, 300, 250, 200, 225, 215, 350, 340
ArrayList<BstData<Integer>> inlist = bstUtil.inorderTraversal();//100, 200, 215, 225, 250, 300,340, 350
ArrayList<BstData<Integer>> postlist = bstUtil.postorderTraversal();//215, 225, 200, 250, 340, 350, 300, 100
ArrayList<BstData<Integer>> breathList = bstUtil.breathFirstTraversal(); //100, 300, 250, 350, 200, 340, 225, 215
ArrayList<BstData<Integer>> depthList = bstUtil.depthFirstTraversal();//100, 300, 250, 200, 225, 215, 350, 340
int i = 0;
i++;
}
}
数据结构与算法 -- 二叉搜索树(java实现)
最新推荐文章于 2025-05-12 10:01:42 发布
本文详细介绍了二叉搜索树的数据结构实现,包括添加、查找、删除节点的方法,以及前序、中序、后序、深度优先和广度优先遍历算法。通过具体实例展示了如何构建和操作二叉搜索树。
1354

被折叠的 条评论
为什么被折叠?



