java 数据结构 二叉查找树的简单实现
2018-01-16 17:50
666 查看
什么是二叉查找树
二叉查找树是一种树结构。首先是二叉树。它表示每个节点最多有两个子节点,而二叉查找树,它还要求左子节点必须比右子节点小。对于这个结构,我们以下几个操作的实现:
树中的元素必须能比较
这里的比较,我们不用equals和==,我们要判断它与节点中元素的大小关系,所以这里我们有2种实现方案:1. 元素实现Comparable接口,重写它的compareTo方法
2. 在二叉树的构造方法中传入特定的Comparator比较器进行比较
/** * 比较器 */ private Comparator<T> comparator; public BinarySearchTree() { root = null; comparator = null; } /** * 带有指定比较器的构造方法 * @param comparator */ public BinarySearchTree(Comparator<T> comparator) { root = null; this.comparator = comparator; } /** * 自己实现一个compare方法 * 如果在构造时传入了相应的比较器,则用传入比较器的compare方法 * 若没有传,则强转成comparable进行比较 * * @param t1 * @param t2 * @return */ private int compare(T t1, T t2) { /** * 如果比较器不为null */ if (comparator != null) { return comparator.compare(t1, t2); } return ((Comparable) t1).compareTo(t2); }
insert操作
当执行插入操作时,思路就是比较插入元素和节点元素的大小,若插入元素大,则往节点右边走,相反则往节点左边走,最后当节点的左边或右边为null的时候,就把元素插入进去了.若碰到插入元素重复的情况则不管public void insert(T t) { root = insert(t, root); } private BinaryNode<T> insert(T t, BinaryNode binaryNode) { if (binaryNode == null) { BinaryNode node = new BinaryNode(t, null, null); return node; } Object element = binaryNode.element; int compare = compare(t, (T) element); if (compare == -1) { // 说明t 比 element 小 binaryNode.left = insert(t, binaryNode.left); } else if (compare == 1) { // 说明t 比 element 大 binaryNode.right = insert(t, binaryNode.right); } else ; /** * 若t和element一样大则不做任何事情 */ /** * 把根返回 */ return binaryNode; }
contains操作
和insert操作基本一个思路,就是比较元素和节点元素大小来判断往左走还是往右走,若碰到元素和节点元素相等的情况则返回true,否则返回falsepublic boolean contains(T t) { return contains(t, root); } private boolean contains(T t, BinaryNode binaryNode) { if (binaryNode == null) { return false; } Object element = binaryNode.element; int compare = compare(t, (T) element); if (compare == 1) { return contains(t, binaryNode.right); } else if (compare == -1) { return contains(t, binaryNode.left); } else { return true; } }
findMin和findMax操作
很简单,findMin就是一直往左走,知道节点的左节点为null时,则该节点的元素最小,findMax则相反,这里我们findMax用递归实现,findMin用循环实现public T findMin() { BinaryNode min = findMin(root); if (min != null) { return (T) min.element; } return null; } public T findMax() { BinaryNode max = findMax(root); if (max != null) { return (T) max.element; } return null; } private BinaryNode findMin(BinaryNode binaryNode) { if (binaryNode != null) { while (binaryNode.left != null) { binaryNode = binaryNode.left; } } return binaryNode; } private BinaryNode findMax(BinaryNode binaryNode) { if (binaryNode == null) { return null; } if(binaryNode.right != null) { return findMax(binaryNode.right); } return binaryNode; }
remove操作
这个比较麻烦,因为有几种情况:删除的节点没有子节点。。。。这个比较简单,直接删除即可
删除的节点有一个子节点。。。。我们通过把要删除节点的父节点的链绕过该节点,在删除
删除的节点有两个子节点。。。这种情况就比较麻烦了,我们先拿到这个节点的右子节点,然后一直往左拿到最小的那个节点,用这个最小节点的数据代替我们要删除的节点,然后把这个最小的节点删除即可
public boolean remove(T t) { BinaryNode remove = remove(t, root); if (remove != null) { return true; } return false; } private BinaryNode remove(T t, BinaryNode binaryNode) { if (binaryNode == null) { return binaryNode; } int compare = compare(t, (T) binaryNode.element); if (compare == -1) { binaryNode.left = remove(t, binaryNode.left); } else if (compare == 1) { binaryNode.right = remove(t, binaryNode.right); } else if (binaryNode.left != null && binaryNode.right != null) { /** *这儿注释的三局代码,findMin会搜索一遍,remove又会搜索一遍,所以我们写一个特殊的removeMin方法来避免这个操作 */ // BinaryNode min = findMin(binaryNode.right); // binaryNode.element = min.element; // binaryNode.right = remove((T) min.element, binaryNode.right); removeMin(binaryNode); } else { binaryNode = binaryNode.left == null ? binaryNode.right : binaryNode.left; } return binaryNode; } private void removeMin(BinaryNode binaryNode) { if (binaryNode == null) { return ; } BinaryNode node = binaryNode.right; BinaryNode parentNode = null; while (true) { if(node.left != null) { parentNode = node; node = node.left; } else { Object element = node.element; binaryNode.element = element; parentNode.left = node.right; break; } } }
代码
package collection; import java.util.Comparator; /** * Created by sunhan on 2018/1/14. */ public class BinarySearchTree<T> { private static class BinaryNode<T> { private BinaryNode<T> left; private BinaryNode<T> right; private T element; public BinaryNode(T t) { this(t, null, null); } public BinaryNode(T t, BinaryNode left, BinaryNode right) { this.element = t; this.left = left; this.right = right; } } /** * 先序遍历 */ public void suffix(){ midIterator(root); } private void suffixIterator(BinaryNode node){ System.out.println(node.element.toString()); if(node.left != null){ suffixIterator(node.left); } if(node.right != null){ suffixIterator(node.right); } } /** * 中序遍历 */ public void mid(){ midIterator(root); } private void midIterator(BinaryNode node){ if(node.left != null){ midIterator(node.left); } System.out.println(node.element.toString()); if(node.right != null){ midIterator(node.right); } } /** * 后序遍历 */ public void back(){ backIterator(root); } private void backIterator(BinaryNode node){ if(node.left != null){ backIterator(node.left); } if(node.right != null){ backIterator(node.right); } System.out.println(node.element.toString()); } /** * 根 */ private BinaryNode<T> root; /** * 比较器 */ private Comparator<T> comparator; public BinarySearchTree() { root = null; comparator = null; } /** * 带有指定比较器的构造方法 * @param comparator */ public BinarySearchTree(Comparator<T> comparator) { root = null; this.comparator = comparator; } /** * 自己实现一个compare方法 * 如果在构造时传入了相应的比较器,则用传入比较器的compare方法 * 若没有传,则强转成comparable进行比较 * * @param t1 * @param t2 * @return */ private int compare(T t1, T t2) { /** * 如果比较器不为null */ if (comparator != null) { return comparator.compare(t1, t2); } return ((Comparable) t1).compareTo(t2); } public void insert(T t) { root = insert(t, root); } private BinaryNode<T> insert(T t, BinaryNode binaryNode) { if (binaryNode == null) { BinaryNode node = new BinaryNode(t, null, null); return node; } Object element = binaryNode.element; int compare = compare(t, (T) element); if (compare == -1) { // 说明t 比 element 小 binaryNode.left = insert(t, binaryNode.left); } else if (compare == 1) { // 说明t 比 element 大 binaryNode.right = insert(t, binaryNode.right); } else ; /** * 若t和element一样大则不做任何事情 */ /** * 把根返回 */ return binaryNode; } public T findMin() { BinaryNode min = findMin(root); if (min != null) { return (T) min.element; } return null; } public T findMax() { BinaryNode max = findMax(root); if (max != null) { return (T) max.element; } return null; } private BinaryNode findMin(BinaryNode binaryNode) { if (binaryNode != null) { while (binaryNode.left != null) { binaryNode = binaryNode.left; } } return binaryNode; } private BinaryNode findMax(BinaryNode binaryNode) { if (binaryNode == null) { return null; } if(binaryNode.right != null) { return findMax(binaryNode.right); } return binaryNode; } public boolean contains(T t) { return contains(t, root); } private boolean contains(T t, BinaryNode binaryNode) { if (binaryNode == null) { return false; } Object element = binaryNode.element; int compare = compare(t, (T) element); if (compare == 1) { return contains(t, binaryNode.right); } else if (compare == -1) { return contains(t, binaryNode.left); } else { return true; } } public boolean remove(T t) { BinaryNode remove = remove(t, root); if (remove != null) { return true; } return false; } private BinaryNode remove(T t, BinaryNode binaryNode) { if (binaryNode == null) { return binaryNode; } int compare = compare(t, (T) binaryNode.element); if (compare == -1) { binaryNode.left = remove(t, binaryNode.left); } else if (compare == 1) { binaryNode.right = remove(t, binaryNode.right); } else if (binaryNode.left != null && binaryNode.right != null) { // BinaryNode min = findMin(binaryNode.right); // binaryNode.element = min.element; // binaryNode.right = remove((T) min.element, binaryNode.right); removeMin(binaryNode); } else { binaryNode = binaryNode.left == null ? binaryNode.right : binaryNode.left; } return binaryNode; } private void removeMin(BinaryNode binaryNode) { if (binaryNode == null) { return ; } BinaryNode node = binaryNode.right; BinaryNode parentNode = null; while (true) { if(node.left != null) { parentNode = node; node = node.left; } else { Object element = node.element; binaryNode.element = element; parentNode.left = node.right; break; } } } }
相关文章推荐
- 数据结构(Java语言)——ArrayList简单实现
- 重温数据结构:二叉查找树的java实现
- 数据结构-Java实现-简单递归
- 数据结构: Java中LinkedList的简单实现
- 数据结构笔记--二叉查找树概述以及java代码实现
- 数据结构(Java语言)——LinkedList简单实现
- 【算法数据结构Java实现】递归的简单剖析及时间复杂度计算
- 数据结构学习笔记之Java实现二叉查找树
- 数据结构-顺序表Java简单实现
- 二叉查找树的数据结构以及实现(JAVA)
- [数据结构]java实现的简单链表的 头/尾插法
- Java数据结构之简单链表的定义与实现方法示例
- 【数据结构和算法】用java简单的实现单链表的基本操作
- Java实现简单数据结构之二叉树结构排序 binary tree
- 数据结构: Java中ArrayList的简单实现
- 数据结构:JAVA_二叉查找树基本实现(上)
- 数据结构--二叉查找树的java实现
- Java数据结构之简单的连接点(link)实现
- Java实现数据结构之二叉查找树
- [数据结构]二叉查找树 简单实现