Binary Search Tree 二叉查找树

来源:互联网 发布:南京大学cssci数据库 编辑:程序博客网 时间:2024/05/18 03:04

Binary Search Tree 二叉查找树

二叉查找树一种二叉树结构,其左子树比根节点小,右子树比根节点大。

定义接口

/** * 定义二叉查找树的接口。元素是可比较的。 * 定义操作:判空、大小、包含、添加、删除、前序遍历、中序遍历、后续遍历 */public interface BinarySearchTree <T extends Comparable<T>> {public boolean isEmpty();public int size();public boolean contains(T item);public void add(T item);public void remove(T item);public List<T> preorder();public List<T> inorder();public List<T> postorder();public List<T> levelorder();}
递归实现

/** * 二叉查找树的递归实现 */public class BSTRecursive<T extends Comparable<T>> implements BinarySearchTree<T> {private Node<T> root;private int size;@Overridepublic boolean isEmpty() {return size == 0;}@Overridepublic int size() {return size;}@Overridepublic boolean contains(T item) {return containsRecursive(root, item);}private boolean containsRecursive(Node<T> root,T item) {if (root == null) {return false;}int cmp = root.item.compareTo(item); // 如果root大于item,查左子树if (cmp > 0) {return containsRecursive(root.left, item);} else if(cmp == 0) {return true;} else {return containsRecursive(root.right, item);}}@Overridepublic void add(T item) {root = addRecursive(root, item);}private Node<T> addRecursive(Node<T> root, T item) {if (root == null) {size++;return new Node<T>(item);}int cmp = root.item.compareTo(item); if (cmp > 0) {root.left = addRecursive(root.left, item);} else if(cmp < 0) {root.right = addRecursive(root.right, item);;}return root;}@Overridepublic void remove(T item) {root = removeRecursive(root, item);}// 删除时,是用右子树最小的来替换private Node<T> removeRecursive(Node<T> root, T item) {if (root == null) {return null;}int cmp = root.item.compareTo(item);if (cmp > 0) {root.left = removeRecursive(root.left, item);} else if(cmp < 0) {root.right = removeRecursive(root.right, item);} else {size--;if (root.left == null) {return root.right;}if (root.right == null) {return root.left;}Node<T> leftMost = findLeftMost(root.right);leftMost.left = root.left;// 如果最左节点是直接右节点,则不更新if (leftMost != root.right) {leftMost.right = root.right;}return leftMost;}return root;}// 找到最左节点后,将其拆下来private Node<T> findLeftMost(Node<T> root) {if (root.left == null) {return root;}Node<T> leftMost = findLeftMost(root.left);if (leftMost == root.left) {root.left = root.left.right;}return leftMost;}@Overridepublic List<T> preorder() {List<T> result = new ArrayList<T>();preorderRecursive(root, result);return result;}// 前序遍历  root, root.left, root.rightprivate void preorderRecursive(Node<T> root, List<T> result) {if (root == null) {return;}result.add(root.item);preorderRecursive(root.left, result);preorderRecursive(root.right, result);}@Overridepublic List<T> inorder() {List<T> result = new ArrayList<T>();inorderRecursive(root, result);return result;}// 终须遍历  root.left, root, root.rightprivate void inorderRecursive(Node<T> root, List<T> result) {if (root == null) {return;}inorderRecursive(root.left, result);result.add(root.item);inorderRecursive(root.right, result);}@Overridepublic List<T> postorder() {List<T> result = new ArrayList<T>();postorderRecursive(root, result);return result;}// 后序遍历 root.left, root.right, root private void postorderRecursive(Node<T> root, List<T> result) {if (root == null) {return;}postorderRecursive(root.left, result);postorderRecursive(root.right, result);result.add(root.item);}@Overridepublic List<T> levelorder() {List<T> result = new ArrayList<T>();List<Node<T>> level = new ArrayList<Node<T>>();level.add(root);levelorderRecursive(level, result);return result;}// level用來存放一层的Node,一层一层向下递归.宽度优先搜索BFSprivate void levelorderRecursive(List<Node<T>> level, List<T> result) {if (level.size() == 0 || level.get(0) == null) {return;}List<Node<T>> newLevel = new ArrayList<Node<T>>();for (Node<T> node : level) {result.add(node.item);if (node.left != null) {newLevel.add(node.left);}if (node.right != null) {newLevel.add(node.right);}}levelorderRecursive(newLevel, result);}private static class Node<T> {T item;Node<T> left;Node<T> right;Node(T item) {this.item = item;}}}

非递归实现

/** * 二叉查找树的非递归实现 */public class BST<T extends Comparable<T>> implements BinarySearchTree<T> {private Node<T> root;private int size;@Overridepublic boolean isEmpty() {return size == 0;}@Overridepublic int size() {return size;}@Overridepublic boolean contains(T item) {Node<T> runner = root;while(runner != null) {int cmp = runner.item.compareTo(item);if (cmp > 0) {runner = runner.left;} else if (cmp == 0) {return true;} else {runner = runner.right;}}return false;}@Overridepublic void add(T item) {if (root == null) {root = new Node<T>(item);size++;return;}Node<T> runner = root;while(true) {int cmp = runner.item.compareTo(item);if (cmp > 0) {if (runner.left == null) {runner.left = new Node<T>(item);size++;return;} else {runner = runner.left;}} else if (cmp < 0) {if (runner.right == null) {runner.right = new Node<T>(item);size++;return;} else {runner = runner.right;}} else {return;}}}@Overridepublic void remove(T item) {Node<T> dummyRoot = new Node<T>(null);dummyRoot.left = root;Node<T> runner = root;Node<T> parent = dummyRoot;boolean isLeft = true;while(runner != null) {int cmp = runner.item.compareTo(item);if (cmp > 0) {parent = runner;runner = runner.left;isLeft = true;} else if(cmp < 0) {parent = runner;runner = runner.right;isLeft = false;} else {if (runner.left == null) {if (isLeft) {parent.left = runner.right;} else {parent.right = runner.right;}break;}if (runner.right == null) {if (isLeft) {parent.left = runner.left;} else {parent.right = runner.left;}break;}// 找到替换节点Node<T> subRunner = runner.right;Node<T> subParent = runner;while(subRunner.left != null) {subParent = subRunner;subRunner = subRunner.left;}if (subParent != runner) {subParent.left = subRunner.right;subRunner.right = runner.right;}subRunner.left = runner.left;if (isLeft) {parent.left = subRunner;} else {parent.right = subRunner;}size--;break;}}root = dummyRoot.left;}@Overridepublic List<T> preorder() {List<T> result = new ArrayList<T>();if (root == null) {return result;}// stack先入后出,先放right,再放left。Deque<Node<T>> stack = new ArrayDeque<Node<T>>();stack.push(root);while(!stack.isEmpty()) {Node<T> runner = stack.pop();result.add(runner.item);if(runner.right != null) {stack.push(runner.right);}if (runner.left != null) {stack.push(runner.left);}}return result;}@Overridepublic List<T> inorder() {List<T> result = new ArrayList<T>();if (root == null) {return result;}Deque<Node<T>> stack = new ArrayDeque<Node<T>>();Node<T> runner = root;while(runner != null || !stack.isEmpty()) {while(runner != null) {stack.push(runner);runner = runner.left;}runner = stack.pop();result.add(runner.item);if (runner.right != null) {runner = runner.right;} else {// 为了下一次pop,置为nullrunner = null;}}return result;}@Overridepublic List<T> postorder() {List<T> result = new ArrayList<T>();if (root == null) {return result;}Deque<Node<T>> stack = new ArrayDeque<Node<T>>();// 用来标记根节点是否访问过。HashSet<Node<T>> set = new HashSet<Node<T>>();Node<T> runner = root;while(runner != null || !stack.isEmpty()) {while(runner != null) {stack.push(runner);runner = runner.left;}runner = stack.peek();// 如果是访问的节点有右子树且未访问过,则访问右子树。如果该节点访问过,则其右子树已经被访问完。if (runner.right != null && set.add(runner)) {runner = runner.right;} else {stack.pop();result.add(runner.item);runner = null;}}return result;}@Overridepublic List<T> levelorder() {List<T> result = new ArrayList<T>();if (root == null) {return result;}// BFS使用queue,先进先出。Queue<Node<T>> queue = new ArrayDeque<Node<T>>();queue.add(root);while(!queue.isEmpty()) {Node<T> runner = queue.poll();result.add(runner.item);if (runner.left != null) {queue.add(runner.left);}if (runner.right != null) {queue.add(runner.right);}}return result;}private static class Node<T> {T item;Node<T> left;Node<T> right;Node(T item) {this.item = item;}}}

删除操作:

1. 待删除节点无左子树或者无右子树,直接把它的子树接到其parent即可:

        

2. 待删除节点右子树没有左节点:



3. 待删除节点右子树有左节点:

      


0 0
原创粉丝点击