一、算法
二叉排序樹(Binary Sort Tree)又稱二叉查找樹(Binary Search Tree),亦稱二叉搜索樹。 它或者是一棵空樹;或者是具有下列性質的二叉樹: (1)若左子樹不空,則左子樹上所有結點的值均小於它的根結點的值; (2)若右子樹不空,則右子樹上所有結點的值均大於它的根結點的值; (3)左、右子樹也分別為二叉排序樹;
不得不說二叉查找樹的插入和刪除非常麻煩,可謂是費了九牛二虎之力才把代碼寫完。支持Insert,Delete,Search,Min,Max,Successor,Predecessor等操作。BST在數據結構中占有很重要的地位,一些高級樹結構都是其的變種,例如AVL樹、紅黑樹等,因此理解BST對於后續樹結構的學習有很好的作用。
二、java代碼
<span style="font-size:14px;">package com.tangbo; public class BinarySearchTree<T extends Comparable<T>> { Node<T> root; public BinarySearchTree() { super(); } /* * 插入一個元素T t */ public void insert(T t) { Node<T> node = new Node<T>(t); if(node.getKey()==null) { throw new IllegalArgumentException("插入的元素不能為空!"); } if(root == null) { root = node; }else { Node<T> temp = root; while(true) { if(node.getKey().compareTo(temp.getKey())>0) { if(temp.getRightNode()==null) { node.setParentNode(temp); temp.setRightNode(node); break; }else { temp = temp.getRightNode(); } }else { if(temp.getLeftNode()==null) { node.setParentNode(temp); temp.setLeftNode(node); break; }else { temp = temp.getLeftNode(); } } } } } //計算該節點的有幾個孩子節點 private int childCount(Node<T> node) { if (node == null) { throw new IllegalArgumentException("節點不能為空"); } int count = 0; if (node.getLeftNode() != null) { count++; } if (node.getRightNode() != null) { count++; } return count; } //刪除一個節點 public void delete(Node<T> node) { if (node == null) { throw new IllegalArgumentException("刪除節點不能為空!"); } int childCount = childCount(node); Node<T> parentNode = node.getParentNode(); if (childCount == 0) { if (parentNode == null) { root = null; } else { if (node == parentNode.getLeftNode()) { parentNode.setLeftNode(null); } else { parentNode.setRightNode(null); } } } else if (childCount == 1) { if (parentNode == null) { if (node.getLeftNode() != null) { root = node.getLeftNode(); node.getLeftNode().setParentNode(null); } else { root = node.getRightNode(); node.getRightNode().setParentNode(null); } } else { if (node == parentNode.getLeftNode()) { if (node.getLeftNode() != null) { parentNode.setLeftNode(node.getLeftNode()); node.getLeftNode().setParentNode(parentNode); } else { parentNode.setLeftNode(node.getRightNode()); node.getRightNode().setParentNode(parentNode); } } else { if (node.getLeftNode() != null) { parentNode.setRightNode(node.getLeftNode()); node.getLeftNode().setParentNode(parentNode); } else { parentNode.setRightNode(node.getRightNode()); node.getRightNode().setParentNode(parentNode); } } } } else { //后繼沒有左孩子 Node<T> successor = min(node); if (successor != node.getRightNode()) { transplant(successor, successor.getRightNode()); successor.setRightNode(node.getRightNode()); node.getRightNode().setParentNode(successor); } transplant(node, successor); successor.setLeftNode(node.getLeftNode()); node.getLeftNode().setParentNode(successor); } } private void transplant(Node<T> u, Node<T> v) { if (u == null) { throw new IllegalArgumentException("節點不能為空"); } if (u.getParentNode() == null) { root = v; } else if (u == u.getParentNode().getLeftNode()) { u.getParentNode().setLeftNode(v); } else { u.getParentNode().setRightNode(v); } if (v != null) { v.setParentNode(u.getParentNode()); } } //查找 public Node<T> search(T key) { Node<T> temp = root; int result; while(root!=null) { result = key.compareTo(temp.getKey()); switch (result) { case 0: return temp; case 1: temp = temp.getRightNode(); break; case -1: temp = temp.getLeftNode(); break; } } return null; } //求節點rootNode下的最小節點 public Node<T> min(Node<T> rootNode) { if(rootNode == null) { throw new IllegalArgumentException("參考節點不能為空!"); }else { while(rootNode.getLeftNode()!=null) { rootNode = rootNode.getLeftNode(); } } return rootNode; } //返回rootNode下最大的節點 public Node<T> max(Node<T> rootNode) { if(rootNode == null) { throw new IllegalArgumentException("參考節點不能為空!"); }else { while(rootNode.getRightNode()!=null) { rootNode = rootNode.getRightNode(); } } return rootNode; } //返回一個節點的后繼 public Node<T> successor(Node<T> rootNode) { if(rootNode==null) { throw new IllegalArgumentException("參考節點不能為空!"); } if(rootNode.getRightNode()!=null) { return min(rootNode.getRightNode()); } Node<T> processNode = rootNode; Node<T> parent = processNode.getParentNode(); //向上迭代 while (parent != null && processNode == parent.getRightNode()) { processNode = parent; parent = processNode.getParentNode(); } return parent; } //返回一個節點的前驅 public Node<T> predecessor(Node<T> rootNode) { if(rootNode==null) { throw new IllegalArgumentException("參考節點不能為空!"); } if(rootNode.getLeftNode()!=null)//有左孩子的情況 { return max(rootNode.getLeftNode()); } Node<T> processNode = rootNode; Node<T> parent = processNode.getParentNode();//向上迭代 while (parent != null && processNode == parent.getLeftNode()) { processNode = parent; parent = processNode.getParentNode(); } return parent; } //根據數組t構建二叉樹 public Node<T> buidBinarySearchTree(T[] t) { for(int i=0;i<t.length;i++) { insert(t[i]); } return root; } } </span>
<span style="font-size:14px;">package com.tangbo; public class Node<T extends Comparable<T>> { private Node<T> leftNode; private T key; private Node<T> rightNode; private Node<T> parentNode; public Node() { super(); } public Node(T t) { key = t; leftNode=null; rightNode = null; parentNode = null; } public Node<T> getLeftNode() { return leftNode; } public void setLeftNode(Node<T> leftNode) { this.leftNode = leftNode; } public Node<T> getRightNode() { return rightNode; } public void setRightNode(Node<T> rightNode) { this.rightNode = rightNode; } public Node<T> getParentNode() { return parentNode; } public void setParentNode(Node<T> parentNode) { this.parentNode = parentNode; } public T getKey() { return key; } public void setKey(T key) { this.key = key; } @Override public String toString() { return key+""; } } </span>
本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。