基礎資料結構與演算法實現(2)—二叉搜尋樹BST
阿新 • • 發佈:2018-12-18
import java.util.LinkedList; import java.util.Queue; public class BST <E extends Comparable<E>> { private class Node{ public E e; public Node left,right; public Node(E e) { this.e=e; left = null; right = null; } } private Node root; private int size; public BST() { root = null; size = 0; } public int size() { return size; } public boolean isEmpty() { return size==0; } //新增操作 public void add(E e) { root = add(root,e); } 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; } //看BST中是否包含元素e public boolean contains(E e) { return contains(root,e); } //看以node為根的BST中是否包含元素e,遞迴演算法 private boolean contains(Node 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); } } //前序遍歷 遞迴實現 public void preOrder() { preOrder(root); } private void preOrder(Node node) { if(node == null) return; System.out.println(node.e); //先訪問節點 preOrder(node.left); preOrder(node.right); } //中序遍歷 按照從小到大的順序(排序樹) 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); } //後序遍歷 //應用之一是為BST釋放記憶體,先釋放子節點 public void postOrder() { postOrder(root); } private void postOrder(Node node) { if(node == null) { return; } postOrder(node.left); postOrder(node.right); System.out.println(node.e); //最後訪問節點 } //層序遍歷(廣度優先遍歷) 用佇列來實現 public void levelOrder() { Queue<Node> q = new LinkedList<>(); q.add(root); //讓節點出隊,同時讓節點的子節點入隊 while(!q.isEmpty()) { Node cur = q.remove(); System.out.println(cur.e); if(cur.left != null) q.add(cur.left); if(cur.right != null) q.add(cur.right); } } //尋找二分搜尋樹的最小元素 public E minimum() { if(size==0) throw new IllegalArgumentException("BST is Empty!"); return minimum(root).e; } private Node minimum(Node node) { if(node.left==null) return node; return minimum(node.left); } //刪除BST中的最小元素 public E removeMin() { E ret = minimum(); root = removeMin(root); return ret; } 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; } //從二分搜尋樹中刪除元素e的節點 public void remove(E e) { root = remove(root,e); } 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.left == null) { Node rightNode = node.right; node.right = null; size--; return rightNode; } //待刪除節點右子樹為空的情況 if(node.right == null) { Node leftNode = node.left; node.left = null; size--; return leftNode; } //待刪除節點左右子樹均不為空的情況 //找到比待刪除節點大的最小節點,即待刪除節點右子樹的最小節點 //用這個節點頂替待刪除節點的位置 Node successor = minimum(node.right); successor.right = removeMin(node.right); successor.left = node.left; node.left = node.right = null; return successor; } } //以前序遍歷實現列印BST @Override public String toString() { StringBuilder res = new StringBuilder(); generateBSTString(root,0,res); return res.toString(); } //生成以node為根節點,深度為depth的描述二叉樹的字串 private void generateBSTString(Node node,int depth,StringBuilder res) { if(node == null) { res.append(generateDepthString(depth)+"null\n"); return; } res.append(generateDepthString(depth)+node.e+"\n"); generateBSTString(node.left, depth+1, res); generateBSTString(node.right, depth+1, res); } //代表深度的符號 private String generateDepthString(int depth) { StringBuilder res = new StringBuilder(); for(int i=0;i<depth;i++) { res.append("-"); } return res.toString(); } }