BST二分搜索树(二叉树)
作者:互联网
java实现二叉树
1、定义数据结点
class Node<E> { E e; Node<E> left, right; int size, depth;// 扩展 public Node() { this.e = null; this.left = null; this.right = null; } public Node(E e) { this.e = e; this.left = null; this.right = null; } }
2、插入结点
/** * BST添加元素 * * @return */ public void add(E e) { root = add(root, e); } /** * 向以node为根的二分搜索树中插入元素e,递归算法 返回插入新节点后二分搜索树的根 * * @return */ private Node<E> add(Node<E> node, E e) { if (node == null) { size++; return new Node<E>(e); } if (e.compareTo(node.e) < 0) { node.left = add(node.left, e); } else if (e.compareTo(node.e) > 0) { node.right = add(node.right, e); } return node; }
3、查询最小值
/** * BST最小值 * * @param node */ public E min() { if (isEmpty()) throw new IllegalArgumentException("BST is isEmpty"); return min(root).e; } private Node<E> min(Node<E> node) { if (node.left == null) return node; return min(node.left); }
4、查询最大值
/** * BST最大值 * * @param node */ public E max() { if (isEmpty()) throw new IllegalArgumentException("BST is isEmpty"); return max(root).e; } private Node<E> max(Node<E> node) { if (node.right == null) return node; return max(node.right); }
5、判断是否存在
/** * 判断是否存在 * * @param e * @return */ public boolean contains(E e) { return contains(root, e); } private boolean contains(Node<E> node, E e) { if (node == null) return false; if (e.compareTo(node.e) == 0) return true; //左子树 else if (e.compareTo(node.e) < 0) return contains(node.left, e); //右子树 else return contains(node.right, e); }
6、删除最小值
/** * BST删除最小值 * * @param node */ public E removeMin() { E min = min(); root = removeMin(root); return min; } /** * 向以node为根的二分搜索树中删除元素,递归算法 返回待删除节点后二分搜索树的根 * */ private Node<E> removeMin(Node<E> node) { if (node.left == null) { BST<E>.Node<E> right = node.right; node = null; return right;// 返回最左节点 } // 存在右子树 node.left = removeMin(node.left); size--; return node; }
7、删除最大值
/** * BST删除最大值 * * @param node */ public E removeMax() { E max = max(); root = removeMax(root); return max; } /** * 向以node为根的二分搜索树中删除元素,递归算法 返回待删除节点后二分搜索树的根 * */ private Node<E> removeMax(Node<E> node) { if (node.right == null) { Node<E> left = node.left; left.right = null; return left;// 返回最左节点 } // 存在右子树 node.right = removeMax(node.right); size--; return node; }
8、删除指定元素
/** * BST删除指定元素 * * @param node */ public void remove(E e) { root = remove(root, e); } /** * 向以node为根的二分搜索树中删除元素,递归算法 返回待删除节点后二分搜索树的根 * 1、头结点 * 2、叶子节点 * 3、非叶子节点:①只有右子树;②只有左子树;③有左右子树 * */ private Node<E> remove(Node<E> node, E e) { if (node == null) return null; if (e.compareTo(node.e) == 0) { size--; //①只有右子树; if (node.left == null) return node.right; //②只有左子树 if (node.right == null) return node.left; // ③有左右子树 重新选举节点:后驱法(右子树最小值)、前驱法(左子树最大值)
Node<E> rightMinNode = removeMin(node.right);
rightMinNode.left = node.left;
rightMinNode.right = node.right;
return rightMinNode;
// Node<E> lefgMaxNode = removeMax(node.left);
// lefgMaxNode.left = node.left;
// lefgMaxNode.right = node.right;
// return lefgMaxNode ;
} else if (e.compareTo(node.e) < 0) {
node.left = remove(node.left, e); } else { node.right = remove(node.right, e); } return node; }
9、前序遍历
/** * BST前序遍历-非递归 */ public void preOrderTraverseNR() { Stack<Node<E>> stack = new Stack<Node<E>>(); stack.push(root); while (!stack.isEmpty()) { Node<E> cur = stack.pop(); System.out.println(cur.e); // 栈:先进后出特性决定,右子树先入栈 if (cur.right != null) stack.push(cur.right); if (cur.left != null) stack.push(cur.left); } }
/** * BST前序遍历-深度优先遍历(Depth First Search) * * @param node */ public void preOrderTraverse() { preOrderTraverse(root); } /** * BST前序遍历:①. 根----->左------->右 ②. 根据前序遍历的结果可知第一个访问的必定是root结点 * * @param node */ private void preOrderTraverse(Node<E> node) { if (node == null) return; System.out.println(node.e); preOrderTraverse(node.left); preOrderTraverse(node.right); }
10、中序遍历
/** * BST中序遍历-非递归 */ public void midOrderTraverseNR() { Stack<Node<E>> stack = new Stack<Node<E>>(); Node<E> cur = root; while (cur!= null || !stack.isEmpty()) { //一路向左走到最左侧节点 while(cur != null) { stack.push(cur); cur = cur.left; } //此时到达最左侧节点 cur = stack.pop(); System.out.println(cur.e); cur = cur.right; } }
/** * BST中序遍历: * * @param node */ public void midOrderTraverse() { midOrderTraverse(root); } /** * BST中序遍历:①. 左----->根------->右 ②. 根据中序遍历的结果,再结合前序遍历的root结点去划分root结点的左右子树。 * * @param node */ private void midOrderTraverse(Node<E> node) { if (node == null) return; midOrderTraverse(node.left); System.out.println(node.e); midOrderTraverse(node.right); }
11、后续遍历
/** * BST后序遍历-非递归 */ public void afterOrderTraverseNR() { Stack<Node<E>> stack = new Stack<Node<E>>(); Node<E> cur = root; Node<E> pre = null; while (cur != null || !stack.isEmpty()) { //所有左节点入栈 while(cur != null) { stack.push(cur); cur = cur.left; } //此时到达最左侧节点 cur = stack.pop(); //没有右结点 if(cur.right == null) { System.out.println(cur.e); pre = cur; cur = null;//已遍历结点置空 continue; } //二次访问父节点 if(cur.right == pre) { System.out.println(cur.e); pre = cur; cur = null;//已遍历结点置空 continue; } //父节点二次入栈 stack.push(cur); //访问右结点 cur = cur.right; } }
/** * BST后序遍历: * * @param node */ public void afterOrderTraverse() { afterOrderTraverse(root); } /** * BST后序遍历 * 应用:内存释放 ①. 左------>右------>根 ②. 根据后序遍历的结果可知最后访问的必定是root结点。 * * @param node */ private void afterOrderTraverse(Node<E> node) { if (node == null) return; afterOrderTraverse(node.left); afterOrderTraverse(node.right); System.out.println(node.e); }
标签:二分,node,right,return,cur,BST,二叉树,null,left 来源: https://www.cnblogs.com/wangymd/p/16456288.html