二叉树:每个节点最多有两个孩子,是一种动态数据结构,具有递归结构。
//二叉树的节点定义
class Node<E extends Comparable<E>> {
E e;
Node left;
Node right;
public Node(e) {
this.e = e;
left = null;
right = null;
}
public String toString() {
return e.toString();
}
}
其中空树和只有根节点的树都是二叉树。
满二叉树:对于每一个非叶子节点都有两个节点。
-
二分搜索数(BST)
-
对于每一个节点的值,都大于其左子树的所有节点,小于其右子树的所有节点。另外存储的元素是可比较的。
public class BST<E extends Comparable<E>> { private Node root; //BST的根节点 private int size; //BST的大小 public BST() { root = null; size = 0; } }
BST的一些重要操作
-
contains(E e)
:判断元素e是否在该BST中public boolean contains(E e) { return contains(root, e); } //在以node为根的BST中,判断元素e是否存在于BST中 private boolean contains(Node node, E e) { if(node == null) { //没找到e元素 return false; } if(e.compareTo(node.e) < 0) { //去左子树 return contains(node.left, e); }else if(e.compareTo(node.e) > 0) { //去右子树 return contains(node.right, e); }else{ //找到了e return true; } }
-
add(E e)
:向BST中添加元素epublic void add(E e) { if(root == null) { //空树 root = new Node(e); size ++ }else{ add(root, e); } } //在以node为根的BST中添加一个元素,并返回操作之后的以node为根节点的BST private Node add(Node node, E e) { if(node == null) { //找待插入的位置 size ++; //生成新结点,并向上层返回,与上层链接 return new Node(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; }
-
getMin()
:获取BST中的最小值节点的值public E getMin() { if(isEmpty()) { throw new RuntimeException("Empty BST!"); } return getMin(root).e; } private Node getMin(Node node) { if(node.left == null) { return node; } return getMin(node.left); }
-
getMax()
:获取BST中最大节点的值public E getMax() { if(isEmpty()) { throw new RuntimeException("Empty BST!"); } return getMax(root).e; } private Node getMax(Node node) { if(node.right == null) { return node; } return getMax(node.right); }
-
remove()
:移除操作public void remove(E e) { //注意:root仍然需要承接删除节点后的树 root = remove(root, e); } public E removeMin() { root = remove(root); return getMin(); } //在以node为根的BST中,删除元素e,返回删除之后的新树 private Node removeMin(Node node) { if(node.left == null) { Node rightNode = node.right; node.right = null; size --; return rightNode; } node.left = removeMin(node.left); return node; } private Node remove(Node node, E e) { if(node == null) { return null; } if(e.compareTo(node.e) < 0) { node.left = remove(node.left, e); return node; }else if(e.compareTo(node.e) > 0){ node.right = remove(node.right, e); return node; }else{ if(node.right == null) { //没有右子树的情况 Node leftNode = node.left; node.left = null; size --; return leftNode; } if(node.left == null) { //没有左子树的情况 Node rightNode = node.right; node.right = null; size --; return rightNode; } //左右子树均存在 //获取待删除节点的右子树的最小节点 Node successor = getMin(node.right); //后继结点的右子树接替删除右子树中最小节点后的新树 successor.right = removeMin(node.right); successor.left = node.left; node.left = node.right = null; } }
-
遍历BST
-
先序遍历
//递归写法 public void preOrder() { preOrder(root); } //在以node为根的BST中先序遍历各节点 private void preOrder(Node node) { if(node == null) { return; } System.out.println(node.e); preOrder(node.left); preOrder(node.right); } //非递归写法:借助栈 private List<E> preOrderNR(Node root) { ArrayList<E> res = new ArrayList<>(); if(root == null) { return res; } Stack<Node> stack = new Stack<>(); stack.push(root); while(!statck.isEmpty()) { Node curr = stack.pop(); res.add(curr.e); //左右子节点入栈,先入有孩子 if(curr.right != null) { stack.push(curr.right); } if(curr.left != null) { stack.push(curr.left); } } return res; }
-
中序遍历
public void inOrder() { inOrder(root); } //递归写法 private void inOrder(Node node) { if(node != null) { return; } inOrder(node.left); System.out.println(node.e); inOrder(node.right); } //非递归写法 public void inOrder(Node root) { ArrayList<Integer> res = new ArrayList<>(); if(root == null) return res; Stack<Node> stack = new Stack<>(); Node curr = root; while(curr != null || !stack.isEmpty()) { //当前节点不为空或栈不为空即可循环 if(curr != null) { stack.push(curr); curr = curr.left; }else{ curr = stack.pop(); res.add(curr.e); curr = curr.right; } } return res; }
-
后序遍历
public void postOrder() { postOrder(root); } //递归写法 private void postOrder() { if(node != null) { return; } postOrder(node.left); postOrder(node.right); System.out.println(node.e); } //非递归写法 private void postOrderNR(Node root) { if(root == null) { return; } Stack<Node> traStack = new Stack<>(); Stack<Node> resStack = new Stack<>(); traStack.push(root); while(!traStack.isEmpty()) { Node curr = traStack.pop(); resStack.push(curr); if(curr.left != null) { traStack.push(curr.left); } if(curr.right != null) { traStack.push(curr.right); } } while(!resStack.isEmpty()) { Node curr = resStack.pop(); System.out.println(curr.e); } }
-
层序遍历
//借助队列 private void levelOrder() { if(root == null) { //空树 return; } Queue<Node> queue = new LinkedList<>(); queue.add(root); while(!queue.isEmpty()) { Node curr = queue.remove(); System.out.println(curr.e); if(curr.left != null) { queue.add(curr.left); } if(curr.right != null) { queue.add(curr.right); } } }
-
-