特点
- 左子树的每个结点的值都比根节点小,右子树的每个结点的值都比根节点大
- 中序遍历为一个有序序列
图
二叉搜索树.png
时间复杂度
- 查找 O(logn)
- 插入 O(1)
- 删除 O(logn) 寻找前继结点或者后继结点 替换删除的结点
前继结点:第一个比根节点小的数
后继结点:第一个比根节点大的数
代码实现
public class TreeNode<E> { private TreeNode<E> leftNode; private Integer key; private E data; private TreeNode<E> rightNode; private TreeNode<E> parentNode; public TreeNode(Integer key, E data) { this.key = key; this.data = data; } public TreeNode(TreeNode<E> leftNode, E data, TreeNode<E> rightNode) { this.leftNode = leftNode; this.data = data; this.rightNode = rightNode; } public TreeNode<E> getLeftNode() { return leftNode; } public void setLeftNode(TreeNode<E> leftNode) { this.leftNode = leftNode; } public E getData() { return data; } public void setData(E data) { this.data = data; } public TreeNode<E> getRightNode() { return rightNode; } public void setRightNode(TreeNode<E> rightNode) { this.rightNode = rightNode; } public Integer getKey() { return key; } public void setKey(Integer key) { this.key = key; } public void setParentNode(TreeNode<E> parentNode) { this.parentNode = parentNode; } public TreeNode<E> getParentNode() { return parentNode; } } public class BinarySelectTree<E> { private int size; private TreeNode<E> rootNode; public void insert(Integer key, E data) { if (rootNode == null) { rootNode = new TreeNode<>(key, data); size++; return; } insert(rootNode, key, data); size++; } private void insert(TreeNode<E> treeNode, Integer key, E data) { Integer rootKey = treeNode.getKey(); TreeNode<E> leafNode = new TreeNode<>(key, data); if (rootKey >= key) { if (treeNode.getLeftNode() != null) { insert(treeNode.getLeftNode(), key, data); } else { treeNode.setLeftNode(leafNode); leafNode.setParentNode(treeNode); } } else { if (treeNode.getRightNode() != null) { insert(treeNode.getRightNode(), key, data); } else { treeNode.setRightNode(leafNode); leafNode.setParentNode(treeNode); } } } public E find(Integer key) { if (rootNode != null) { TreeNode<E> eTreeNode = find(rootNode, key); if (eTreeNode != null) return eTreeNode.getData(); } return null; } private TreeNode<E> find(TreeNode<E> treeNode, Integer key) { Integer rootKey = treeNode.getKey(); if (rootKey > key) { if (treeNode.getLeftNode() != null) { return find(treeNode.getLeftNode(), key); } } else if (rootKey < key) { if (treeNode.getRightNode() != null) { return find(treeNode.getRightNode(), key); } } else return treeNode; return null; } public int size() { return size; } public void print(TreeNode<E> treeNode) { System.out.print(treeNode.getData()); } public void pre() { if (rootNode != null) pre(rootNode); } //前序遍历 根 左 右 public void pre(TreeNode<E> treeNode) { print(treeNode); if (treeNode.getLeftNode() != null) pre(treeNode.getLeftNode()); if (treeNode.getRightNode() != null) pre(treeNode.getRightNode()); } public void mid() { if (rootNode != null) mid(rootNode); } //中序遍历 左 根 右 private void mid(TreeNode<E> treeNode) { if (treeNode.getLeftNode() != null) { mid(treeNode.getLeftNode()); } print(treeNode); if (treeNode.getRightNode() != null) mid(treeNode.getRightNode()); } public void post() { if (rootNode != null) post(rootNode); } //后序遍历 左 右 根 public void post(TreeNode<E> treeNode) { if (treeNode.getLeftNode() != null) { post(treeNode.getLeftNode()); } if (treeNode.getRightNode() != null) { post(treeNode.getRightNode()); } print(treeNode); } //层序遍历 public void level(TreeNode<E> treeNode) { MyQueue<TreeNode<E>> queue = new MyQueue<>(20); levelRecursion(queue, treeNode); } private void levelRecursion(MyQueue<TreeNode<E>> queue, TreeNode<E> treeNode) { print(treeNode); if (treeNode.getLeftNode() != null) { queue.push(treeNode.getLeftNode()); } if (treeNode.getRightNode() != null) { queue.push(treeNode.getRightNode()); } while (!queue.isEmpty()) { levelRecursion(queue, queue.pop()); } } public void remove(Integer key) { //1.找到该key //2.找到该key的后继结点 //3.替换 TreeNode<E> node = find(rootNode, key); if (node == null) return; TreeNode<E> postNode ; if (node.getLeftNode() != null && node.getRightNode() != null) { //此时需寻找后继结点 右子树的最小结点 postNode = findPostNode(node.getRightNode()); TreeNode<E> postParentNode = postNode.getParentNode(); postParentNode.setLeftNode(postNode.getRightNode()); postNode.setLeftNode(node.getLeftNode()); postNode.setRightNode(node.getRightNode()); }else { //至少有一个为空 postNode = node.getLeftNode() != null ? node.getLeftNode() : node.getRightNode(); } //判断删除的是左结点还是右结点 TreeNode<E> parentNode = node.getParentNode(); if(parentNode==null){ //删除的是根结点 rootNode = postNode; rootNode.setParentNode(null); return; } TreeNode<E> leftNode = parentNode.getLeftNode(); if (leftNode != null && leftNode == node) { parentNode.setLeftNode(postNode); } else { parentNode.setRightNode(postNode); } postNode.setParentNode(parentNode); } public TreeNode<E> findPostNode(TreeNode<E> node) { if (node.getLeftNode() != null) { findPostNode(node.getLeftNode()); } return node; } }