二叉查找树

你。 提交于 2020-12-17 05:22:10

二叉查找树:Binary Search Tree 

对于二叉树的任何一个节点K,左子树的任意一个节点都小于K,右子树的任意一个节点都大于或等于K,按照中序周游将各个节点打印出来会得到由小到大的排列。

节点定义的接口

/** ADT for binary tree nodes */
public interface BinNode<E> {
  /** Get and set the element value */
  public E element();
  public void setElement(E v);

  /** @return The left child */
  public BinNode<E> left();

  /** @return The right child */
  public BinNode<E> right();

  /** @return True if a leaf node, false otherwise */
  public boolean isLeaf();
}

二叉树的节点定义,实现了上述接口

/**
 * Binary tree node implementation: Pointers to children
 * 
 * @param E
 *            The data element
 * @param Key
 *            The associated key for the record
 */
class BSTNode<Key, E> implements BinNode<E> {
	private Key key; // Key for this node
	private E element; // Element for this node
	private BSTNode<Key, E> left; // Pointer to left child
	private BSTNode<Key, E> right; // Pointer to right child

	/** Constructors */
	public BSTNode() {
		left = right = null;
	}

	public BSTNode(Key k, E val) {
		left = right = null;
		key = k;
		element = val;
	}

二叉树的实现,首先上代码,然后再详细讲解

/** Binary Search Tree */
class BST<Key extends Comparable<? super Key>, E> {
	private BSTNode<Key, E> root; // Root of the BST
	int nodecount; // Number of nodes in the BST

	/** Constructor */
	BST() {
		root = null;
		nodecount = 0;
	}

	/** Reinitialize tree */
	public void clear() {
		root = null;
		nodecount = 0;
	}

	/**
	 * Insert a record into the tree.
	 * 
	 * @param k
	 *            Key value of the record.
	 * @param e
	 *            The record to insert.
	 */
	public void insert(Key k, E e) {
		root = inserthelp(root, k, e);
		nodecount++;
	}

	/**
	 * Remove a record from the tree.
	 * 
	 * @param k
	 *            Key value of record to remove.
	 * @return The record removed, null if there is none.
	 */
	public E remove(Key k) {
		E temp = findhelp(root, k); // First find it
		if (temp != null) {
			root = removehelp(root, k); // Now remove it
			nodecount--;
		}
		return temp;
	}

	/**
	 * Remove and return the root node from the dictionary.
	 * 
	 * @return The record removed, null if tree is empty.
	 */
	public E removeAny() {
		if (root == null)
			return null;
		E temp = root.element();
		root = removehelp(root, root.key());
		nodecount--;
		return temp;
	}

	/**
	 * @return Record with key value k, null if none exist.
	 * @param k
	 *            The key value to find.
	 */
	public E find(Key k) {
		return findhelp(root, k);
	}

	/** @return The number of records in the dictionary. */
	public int size() {
		return nodecount;
	}

	private E findhelp(BSTNode<Key, E> rt, Key k) {
		if (rt == null)
			return null;
		if (rt.key().compareTo(k) > 0)
			return findhelp(rt.left(), k);
		else if (rt.key().compareTo(k) == 0)
			return rt.element();
		else
			return findhelp(rt.right(), k);
	}

	/**
	 * @return The current subtree, modified to contain the new item
	 */
	private BSTNode<Key, E> inserthelp(BSTNode<Key, E> rt, Key k, E e) {
		if (rt == null)
			return new BSTNode<Key, E>(k, e);
		if (rt.key().compareTo(k) > 0)
			rt.setLeft(inserthelp(rt.left(), k, e));
		else
			rt.setRight(inserthelp(rt.right(), k, e));
		return rt;
	}

	/**
	 * Remove a node with key value k
	 * 
	 * @return The tree with the node removed
	 */
	private BSTNode<Key, E> removehelp(BSTNode<Key, E> rt, Key k) {
		if (rt == null)
			return null;
		if (rt.key().compareTo(k) > 0)
			rt.setLeft(removehelp(rt.left(), k));
		else if (rt.key().compareTo(k) < 0)
			rt.setRight(removehelp(rt.right(), k));
		else { // Found it
			if (rt.left() == null)
				return rt.right();
			else if (rt.right() == null)
				return rt.left();
			else { // Two children
				BSTNode<Key, E> temp = getmin(rt.right());
				rt.setElement(temp.element());
				rt.setKey(temp.key());
				rt.setRight(deletemin(rt.right()));
			}
		}
		return rt;
	}

	private BSTNode<Key, E> getmin(BSTNode<Key, E> rt) {
		if (rt.left() == null)
			return rt;
		return getmin(rt.left());
	}

	
	private BSTNode<Key, E> deletemin(BSTNode<Key, E> rt) {
		if (rt.left() == null)
			return rt.right();
		rt.setLeft(deletemin(rt.left()));
		return rt;
	}

	
	private void printhelp(BSTNode<Key, E> rt) {
		if (rt == null)
			return;
		printhelp(rt.left());
		printVisit(rt.element());
		printhelp(rt.right());
	}

	private StringBuffer out;

	public String toString() {
		out = new StringBuffer(100);
		printhelp(root);
		return out.toString();
	}

	private void printVisit(E it) {
		out.append(it + " ");
	}
	
	public static void main(String[]args){
		BST<Integer, Integer> D1 = new BST<Integer, Integer>();
		D1.insert(70, 70);
		D1.insert(35, 35);
	    D1.insert(20, 20);
	    D1.insert(17, 17);
	    D1.insert(15, 15);
	    D1.insert(19, 19);
	    D1.insert(100, 110);
	    D1.insert(90, 90);
	    D1.insert(95, 95);
	    System.out.println(D1.toString());
	    System.out.println(D1.find(100));
	}

}

二叉树的查找,添加,删除都是递归的典型应用

查找

首先是在二叉树中查找一个节点,首先判断根节点与要查找的元素的关键字的大小,如果等于就直接返回,大于就查找左子树,小于就查找右子树,进行递归。

private E findhelp(BSTNode<Key, E> rt, Key k) {
		if (rt == null)
			return null;
		if (rt.key().compareTo(k) > 0)
			return findhelp(rt.left(), k);
		else if (rt.key().compareTo(k) == 0)
			return rt.element();
		else
			return findhelp(rt.right(), k);
	}

删除

从BST中删除值最小的节点,只需要沿着左边的链不断下移就可以找到最小的节点,删除s只需要把s父节点原来指向s的指针指向s的右节点。

private BSTNode<Key, E> deletemin(BSTNode<Key, E> rt) {
		if (rt.left() == null)
			return rt.right();
		rt.setLeft(deletemin(rt.left()));
		return rt;
	}

回到根节点的路径上的各个节点的左指针都被重新赋值了


如何从bst删除任意一个位置的节点呢?

首先找到这个节点r。如果r没有子节点,将r的父节点的指向它的指针设为null,如果r有一个子节点,将R的父节点指向它的指针改为指向r的子节点。如果r有两个子节点,对右子树调用deletemin,并将函数的返回值代替被删除的值

private BSTNode<Key, E> removehelp(BSTNode<Key, E> rt, Key k) {
		if (rt == null)
			return null;
		if (rt.key().compareTo(k) > 0)
			rt.setLeft(removehelp(rt.left(), k));
		else if (rt.key().compareTo(k) < 0)
			rt.setRight(removehelp(rt.right(), k));
		else { // Found it
			if (rt.left() == null)
				return rt.right();
			else if (rt.right() == null)
				return rt.left();
			else { // Two children
				BSTNode<Key, E> temp = getmin(rt.right());
				rt.setElement(temp.element());
				rt.setKey(temp.key());
				rt.setRight(deletemin(rt.right()));
			}
		}
		return rt;
	}

插入节点

private BSTNode<Key, E> inserthelp(BSTNode<Key, E> rt, Key k, E e) {
		if (rt == null)
			return new BSTNode<Key, E>(k, e);
		if (rt.key().compareTo(k) > 0)
			rt.setLeft(inserthelp(rt.left(), k, e));
		else
			rt.setRight(inserthelp(rt.right(), k, e));
		return rt;
	}

如何按层打印二叉树

参照图的广度遍历

public void printlevel(){
		Queue<BSTNode> queue = new LinkedList<BSTNode>();
		System.out.println(root.element());
		queue.offer(root);
		while (queue.size()!=0) {
			BSTNode<Key, E> temp = queue.poll();
			if (temp.left()!=null) {
				System.out.println(temp.left().element());
				queue.offer(temp.left());
			}
			if (temp.right()!=null) {
				System.out.println(temp.right().element());
				queue.offer(temp.right());
			}
		}
	}

测试

public static void main(String[]args){
		BST<Integer, Integer> D1 = new BST<Integer, Integer>();
		D1.insert(70, 70);
		D1.insert(35, 35);
	    D1.insert(20, 20);
	    D1.insert(17, 17);
	    D1.insert(15, 15);
	    D1.insert(89, 89);
	    D1.insert(100, 100);
	    D1.insert(90, 90);
	    D1.insert(110, 110);
//	    System.out.println(D1.toString());
	    D1.printlevel();
	}

获取树的高度

public int getHeight(BSTNode<Key, E> root){
		if (root==null) {
			return 0;
		}else{
			return 1+Math.max(getHeight(root.left()),getHeight(root.right()));
		}
	}


给定一个有序整数数组,元素各不相同且升序排列,如何创建一颗高度最小的二叉查找树

让数组中间点成为根节点

将数组左半部分插入左子树

将数组右半部分插入右子树

递归处理

public BSTNode<Key, E> createMinimalBST(Key[] key,E[] ele,int start,int end){
		if(end < start){
			return null;
		}
		int mid=(start+end)/2;
		BSTNode<Key, E> temp=new BSTNode<Key, E>(key[mid],ele[mid]);
		System.out.println(temp.element());
		temp.setLeft(createMinimalBST(key, ele, start, mid-1));
		temp.setRight(createMinimalBST(key, ele, mid+1, end));
		return temp;
	}

测试代码:

public static void main(String[]args){
		BST<Integer, Integer> D1 = new BST<Integer, Integer>();
		Integer[] key={1,2,3,4,5,6,7,8,9};
		Integer[] ele={1,2,3,4,5,6,7,8,9};
		D1.root=D1.createMinimalBST(key,ele, 0, key.length-1);
		System.out.println(D1.toString());
	    System.out.println(D1.getHeight(D1.root));

	}


易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!