二分搜索樹刪除任一節點-Hubbard Deletion

 

package com.xmg.tree;

import java.util.LinkedList;
import java.util.Queue;

/**
 * 二分搜索樹---不一定是完全二叉樹
 *
 * BST -- binary search tree
 *
 * 查找表的實現-字典數據結構
 *
 * 高效,查找,插入,刪除都可以
 */
public class BinaryTree <Key extends Comparable<Key>,Value>{


	private class Node{
		private Key key;
		private Value value;
		private Node left;
		private Node right;
		private Node(Key key,Value value){
			this.key = key;
			this.value = value;
			this.left = this.right = null;
		}

		private Node(Node node){
			this.right = node.right;
			this.left = node.left;
			this.key = node.key;
			this.value = node.value;
		}

	}
	private Node root;
	private int count;
	public BinaryTree(){
		root = null;
		count = 0;
	}

	public int size(){
		return count;
	}

	boolean isEmpty(){
		return count == 0;
	}

	public void insert(Key key,Value value){
		root = insert(root,key,value);
	}

	public Value search(Key key){
		return search(root,key);
	}

	public void preOrder(){
		preOrder(root);
	}

	public void inOrder(){
		inOrder(root);
	}

	public void postOrder(){
		postOrder(root);
	}



	/**
	 * 是否包含key值
	 * @param key
	 * @return
	 */
	public boolean contain(Key key){
		return contain(root,key);
	}

	/**
	 * 向以node爲根的二叉搜索樹中,插入節點(key,value)
	 * 返回插入新節點後的二叉搜索樹的根
	 * @param node
	 * @param key
	 * @param value
	 * @return
	 */
	private Node insert(Node node, Key key, Value value) {

		if (node == null) {
			count++;
			return new Node(key, value);
		}
		if (key == node.key) {
			node.value = value;
		} else if (key.compareTo(node.key) < 0) {
			node.left = insert(node.left, key, value);
		} else {
			node.right = insert(node.right, key, value);
		}
		return node;
	}

	//非遞歸插入
	private Node insertNode(Node node,Key key, Value value){
		Node newNode = new Node(key,value);
		if(node == null){
			count++;
			node = newNode;
		}
		while(node.left!=newNode && node.right!= newNode){
			if(key.compareTo(node.key)<0){
				if(node.left == null){
					node.left = newNode;
				}else{
					node = node.left;
				}
			}else{
				if(node.right == null){
					node.right = newNode;
				}else{
					node = node.right;
				}
			}
		}
		return node;
	}


	private boolean contain(Node node,Key key){
		if(node == null){
			return false;
		}
		if(node.key == key){
			return true;
		}else if(key.compareTo(node.key)<0){
			return contain(node.left,key);
		}else{
			return contain(node.right,key);
		}
	}

	/**
	 * 在以node爲根的二叉搜索樹中查找key所對應的value
	 * @param node
	 * @param key
	 * @return
	 */
	private Value search(Node node,Key key){
		if(node == null){
			return null;
		}
		if(key == node.key){
			return node.value;
		}else if(key.compareTo(node.key)<0){
			return search(node.left,key);
		}else{
			return search(node.right,key);
		}
	}

	/**
	 * 前序遍歷
	 * @param node
	 */
	private void preOrder(Node node){
		if(node!= null){
			System.out.println(node.key+"  "+node.value);
			preOrder(node.left);
			preOrder(node.right);
		}
	}

	/**
	 * 中序遍歷
	 * @param node
	 */
	private void inOrder(Node node){
		if(node!= null){
			inOrder(node.left);
			System.out.println(node.key+"  "+node.value);
			inOrder(node.right);
		}
	}

	/**
	 * 後序遍歷
	 * @param node
	 */
	private void postOrder(Node node){
		if(node!= null){
			postOrder(node.left);
			postOrder(node.right);
			System.out.println(node.key+"  "+node.value);
		}
	}

	/**
	 * 層序遍歷,使用queue來作爲輔助空間
	 */
	public void levelOrder(){
		Queue<Node> queue = new LinkedList<>();
		queue.add(root);
		while(!queue.isEmpty()){
			Node node = queue.remove();
			System.out.println(node.key);
			if(node.left!=null){
				queue.add(node.left);
			}
			if(node.right!=null){
				queue.add(node.right);
			}
		}
	}
	//尋找最小值
	public Key minimum(){
		assert count!=0;
		Node minNode = minimum(root);
		return minNode.key;
	}


	//尋找最大值
	public Key maxmum(){
		assert count!=0;
		Node maxNode = maxmum(root);
		return maxNode.key;
	}

	//刪除最小值的節點
	public void removeMin(){
		if(root!=null){
			root = removeMin(root);
		}
	}

	//刪除最大值的節點
	public void removeMax(){
		if(root!=null){
			root = removeMax(root);
		}
	}

	/**
	 * 在以node爲根的二叉搜索樹中,返回最小值的節點
	 * @param node
	 * @return
	 */
	private Node minimum(Node node){
		if(node.left ==null){
			return node;
		}
		return minimum(node.left);
	}

	private Node maxmum(Node node){
		if(node.right == null){
			return node;
		}
		return maxmum(node.right);
	}

	private Node maxmumNotRecursion(Node node){
		while(node!=null){
			if(node.right == null){
				return node;
			}
			node = node.right;
		}
		return null;
	}


	/**
	 * 刪除以node爲根的二叉搜索樹中的最小節點
	 * @param node
	 * @return  刪除節點後新的二分搜索樹的根
	 */
	private Node removeMin(Node node){
		if(node.left == null){
			Node rightNode = node.right;
			node.right = null;
			count--;
			return rightNode;
		}
		node.left = removeMin(node.left);
		return node;
	}

	/**
	 * 刪除以node爲根的二叉搜索樹中的最大節點
	 * @param node
	 * @return  刪除節點後新的二分搜索樹的根
	 */
	private Node removeMax(Node node){
		if(node.right == null){
			Node leftNode = node.left;
			node.left = null;
			count--;
			return leftNode;
		}
		node.right = removeMax(node.right);
		return node;
	}
//------------------------------------------------------------------
//-------------------------------------------------------------------
	/**
	 * 刪除鍵值爲key的節點
	 * @param key
	 */
	public void delete(Key key){
		root = delete(root,key);
	}

	/**
	 * 刪除Key爲key的節點
	 * @param node 根節點
	 * @param key  要刪除的節點的key
	 * @return
	 */
	private Node delete(Node node,Key key){
		if(node == null){
			return null;
		}
		if( key.compareTo(node.key)<0){
			node.left = delete(node.left,key);
			return node;
		}else if(key.compareTo(node.key)>0){
			node.right = delete(node.right,key);
			return node;
		}else{
			if(node.left == null){
				Node rightNode = node.right;
				node.right = null;
				count --;
				return rightNode;
			}
			if(node.right == null){
				Node leftNode = node.left;
				node.left = null;
				count --;
				return leftNode;
			}
			//node.left!=null && node.right!=null;
			Node successor = new Node(minimum(node.right));
			count++;
			successor.right = removeMin(node.right);
			successor.left  = node.left;

			//刪除節點
			node.left = node.right = null;
			count--;
			return successor;
		}

	}
//------------------------------------------------------------------
//-------------------------------------------------------------------
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章