ADT(二叉查找树)和AVL(平衡二叉树)总结

本篇主要针对了ADT(二叉查找树)和AVL树的基本操作进行了总结:包括:创建,删除整树,插入,删除节点,寻找最大、最小数、遍历树操作。

首先是二叉查找树:

/*
 * 二叉查找树 利用泛型创建的二叉查找树是一个泛型类
 */
class BinarySearchTree<AnyType extends Comparable<? super AnyType>>{
	/*
	 * 节点函数
	 */
	private static class BinaryNode<AnyType>{
		
		AnyType element;
		BinaryNode<AnyType> left;
		BinaryNode<AnyType> right;
		
		BinaryNode(AnyType element) {
			this(element,null,null);
		}
		
		BinaryNode(AnyType element , BinaryNode<AnyType> lt,BinaryNode<AnyType> rt){
			this.element = element;
			this.right = rt;
			this.left = lt;
		}
		
	}
	
	private BinaryNode<AnyType> root;
	
	public BinarySearchTree(){
		root = null;
	}
	
	public void makeEmpty(){
		root = null;
	}
	
	public boolean isEmpty(){
		return root == null;
	}
	
	/*
	 * 检测包含方法
	 */
	public boolean contains(AnyType x){
		return contains(x,root);
	}
	/*
	 * 寻找最小值的节点
	 */
	public AnyType findMin(){
		if(isEmpty()){
			;
		}
		return findMin(root).element;
	}
	/*
	 * 寻找最大值的节点
	 */
	public AnyType findMax(){
		if(isEmpty()){
			;
		}
		return findMax(root).element;
	}
	/*
	 * 插入此值的节点
	 */
	public void insert(AnyType x){
		root = insert(x,root);
	}
	/*
	 * 删除此值的节点
	 */
	public void remove(AnyType x){
		root = remove(x,root);
	}
	/*
	 * 打印二叉查找树
	 */
	public void printTree(){
		if(isEmpty()){
			System.out.println("Empty tree");
		}else{
			printTree(root);
		}
	}
	/*
	 * 递归实现二叉查找树中的查询
	 */
	
	private boolean contains(AnyType x , BinaryNode<AnyType> t){
		
		if(t == null){
			return false;
		}
		
		int result = x.compareTo(t.element);
	
		if(result < 0){
			return contains(x, t.left);
		}else if(result > 0){
			return contains(x,t.right);
		}else{
			return true;
		}
	}
	/*
	 * 递归实现二叉查找树中的寻找最小节点
	 */
	private BinaryNode<AnyType> findMin(BinaryNode<AnyType> t){
		if(t == null)
			return null;
		else if(t.left != null)
			return findMin(t.left);
		else
			return t;
	}
	/*
	 * 循环实现二叉查找树中的寻找最大节点
	 */
	private BinaryNode<AnyType> findMax(BinaryNode<AnyType> t){
		
		if(t != null)
			while(t.right != null)
				t = t.right;
		return t;
	}
	/*
	 * 递归实现二叉查找树中插入
	 */
	private BinaryNode<AnyType> insert(AnyType x , BinaryNode<AnyType> t){
		
		if(t== null){
			return  new BinaryNode<AnyType>(x);	
		}
		
		int result = x.compareTo(t.element);
		
		if(result < 0){
			t.left = insert(x,t.left);
		}else if(result > 0){
			t.right = insert(x , t.right);
		}else{
			;
		}
		
		return t;
	}
	/*
	 * 懒惰删除二叉查找树中的节点 如果有两个儿子就把右子树的最大数作为根值、并在右子树中删除
	 */
	private BinaryNode<AnyType> remove(AnyType x , BinaryNode<AnyType> t){
		
		if(t == null)
			return null;
		
		int result = x.compareTo(t.element);
		
		if(result < 0){
			t.left = remove(x,t.left);
		}else if(result > 0){
			t.right = remove(x,t.right);
		}else if(t.left != null && t.right != null){
			t.element = findMin(t.right).element;
			t.right = remove(t.element , t.right);
		}else{
			t = (t.left != null) ? t.left:t.right;
		}
		
		return t;
	}
	/*
	 * 打印二叉查找树
	 */
	private void printTree(BinaryNode<AnyType> t){
		
		if(t !=null){
			printTree(t.left);
			System.out.print(t.element);
			printTree(t.right);
		}
	}
}
</pre><pre name="code" class="java">接下来是AVL树
</pre><pre name="code" class="java"><pre name="code" class="java">/*
 * 平衡树类
 */
class AVLTree<T extends Comparable<? super T>>{
	
	/*
	 * 平衡树节点,比二叉查找树多了一个高度参数,用来检测左右子树高度差
	 */
	private static class AvlNode<T>{
		 T element;
		 AvlNode<T> left;
		 AvlNode<T> right;
		 int height;
		
		AvlNode(T element){
			this(element, null , null);
		}
		
		AvlNode(T element , AvlNode<T> lt , AvlNode<T> rt){
			this.element = element;
			this.left = lt;
			this.right = rt;
			this.height = 0;
		}
		
	}
	
	private AvlNode<T> root;
	
	AVLTree(){
	    root = null;
	}
	
	public void makeEmpty(){
		root = null;
	}
	
	public boolean isEmpty(){
		return root == null;
	}
	
	public void insert(T x){
		root =  insert(x , root);
	}
	
	public T findMin(){
		return findMin(root);
	}
	
	public T findMax(){
		return findMax(root);
	}
	
	public void remove(T x){
		root =  remove(x ,root);
	}
	
	public boolean contains(T x){
		return contains(x,root);
	}
	
	public void printTree(){
		if(isEmpty())
			System.out.println("Empty tree");
		else
			printTree(root);
	}
	
	/*
	 * AVL树 插入操作:1.判断插入点,2.检测左右树高的差距是否符合要求 3.树高不符合AVL要求时,判断引起原因,进行相应的旋转操作
	 */
	
	private AvlNode<T> insert(T x, AvlNode<T> t){
		if(t == null)
			return new AvlNode<T>(x , null ,null);
		
		int result = x.compareTo(t.element);
		
		if(result < 0){
			t.left = insert(x, t.left);
			if(height(t.left) - height(t.right) ==2){
				if(x.compareTo(t.left.element) < 0)
					t = rotateWithLeftChild(t);
				else
					t = doubleWithLeftChild(t);
			}
		}else if(result > 0){
			t.right = insert(x, t.right);
			if(height(t.right) - height(t.left) ==2){
				if(x.compareTo(t.right.element) > 0)
					t = rotateWithRightChild(t);
				else 
					t = doubleWithRightChild(t);
			}
		}else
			;
		t.height = Math.max(height(t.left), height(t.right))+1;
		return t;
	}
	/*
	 * 单旋转 左侧
	 */
	private AvlNode<T> rotateWithLeftChild(AvlNode<T> k2){
		
		AvlNode<T> k1 = k2.left;
		k2.left = k1.right;
		k1.right = k2;
		k2.height = Math.max(height(k2.left), height(k2.right))+1;
		k1.height = Math.max(height(k1.left), height(k1.right))+1;
		return k1;
	}
	/*
	 * 单旋转右侧
	 */
	private AvlNode<T> rotateWithRightChild(AvlNode<T> k2){
		AvlNode<T> k1 = k2.right;
		k2.right = k1.left;
		k1.left = k2;
		k2.height = Math.max(height(k2.left), height(k2.right))+1;
		k1.height = Math.max(height(k1.left), height(k1.right))+1;
		return k1;
	}
	/*
	 * 双旋转左侧(先右旋后左旋)
	 */
	private AvlNode<T> doubleWithLeftChild(AvlNode<T> k3){
		k3.left = rotateWithRightChild(k3.left);
		return rotateWithLeftChild(k3);
	}
	/*
	 * 单旋转右侧(先左旋后右旋)
	 */
	private AvlNode<T> doubleWithRightChild(AvlNode<T> k3){
		k3.right = rotateWithLeftChild(k3.right);
		return rotateWithRightChild(k3);
	}
	
	private T findMin(AvlNode<T> t){
		if(t == null)
			return null;
		else if(t.left !=null)
			return findMin(t.left);
		else 
			return t.element;
	}
	
	private T findMax(AvlNode<T> t){
		
		if(t != null)
			while(t.right != null)
				t= t.right;
		return t.element;
	}
	/*
	 * AVL树的删除节点 1.寻找删除节点的位置 2.判断删除之后树高是否满足AVL要求 3.如果不满足,在对树高较高的树进行判断、旋转 3.比插入相比要
<span style="white-space:pre">	</span> * 加一个非空判断。
	 */
	private AvlNode<T> remove(T x , AvlNode<T> t){
		
		if(t ==null)
			return null;
		
		int result  = x.compareTo(t.element);
		
		if(result < 0){
			t.left = remove(x , t.left);
			if(height(t.right) - height(t.left) == 2){
				if(height(t.right.left) - height(t.right.right) == 1){
					t = doubleWithRightChild(t);
				}else{
					t = rotateWithRightChild(t);
				}
			}
		}else if(result > 0){
			t.right = remove(x ,t.right);
			if(height(t.left) - height(t.right) == 2){
				if(height(t.left.right) - height(t.left.left) == 1){
					t = doubleWithLeftChild(t);
				}else{
					t = rotateWithLeftChild(t);
				}
			}
		}else if(t.right != null && t.left != null){
			if(height(t.left) >= height(t.right)){
				t.element = findMax(t.left);
				t.left = remove(t.element , t.left);
					
			}else {
				t.element = findMin(t.right);
				t.right = remove(t.element , t.right);
			}
		}else{
			t = (t.left != null)? t.left: t.right;
		}
		if(t != null)
		t.height = Math.max(height(t.left), height(t.right))+1;
		return t;
	}
	
	/*
	 * AVL树查询
	 */
	private boolean contains(T x, AvlNode<T> t){
		if(t == null)
			return false;
		
		int result  = x.compareTo(t.element);
		if(result < 0)
			return contains(x, t.left);
		else if(result > 0)
			return contains(x, t.right);
		else
			return true;
	}
	
	/*
	 * 遍历AVL树
	 */
	private void printTree(AvlNode<T> t){
		if(t != null){
			printTree(t.left);
			System.out.print(t.element.toString() +"(" +height(t)+")");
			printTree(t.right);
		}
	}
	public int height(){
		return height(root);
	}
	private int height(AvlNode<T> t){
		
		return t == null? -1:t.height;
		
	}
	
	
	
}

测试程序

<pre name="code" class="java">public class TreeTest {
	public static void main(String[] args){
		BinarySearchTree<Integer> BST = new BinarySearchTree<>();
		BST.insert(3);
		BST.insert(1);
		BST.insert(4);	
		BST.insert(6);
		BST.insert(9);
		BST.insert(2);
		BST.insert(5);
		BST.insert(7);
		
		BST.printTree();
		System.out.println();
		if(BST.contains(5)){
			System.out.println("Contains five");
		}
		BST.remove(5);
		
		BST.printTree();
		System.out.println();
		System.out.println(BST.findMax()+"");
		System.out.println(BST.findMin()+"");
		if(!BST.contains(5)){
			System.out.println("Contains not five");
		}
		
		AVLTree<Integer> AVLT = new AVLTree<>();
		AVLT.insert(3);
		AVLT.insert(1);
		AVLT.insert(4);	
		AVLT.insert(6);
		AVLT.insert(9);
		AVLT.insert(2);
		AVLT.insert(5);
		AVLT.insert(7);
		
		AVLT.printTree();
		System.out.println();
		 System.out.printf("== 高度: %d\n", AVLT.height());
		if(AVLT.contains(5)){
			System.out.println("I am here");
		}
		if(!AVLT.contains(8))
			System.out.println("I am not here");
		
		System.out.println(AVLT.findMax()+"");
		System.out.println(AVLT.findMin()+"");
		

		AVLT.remove(2);
		AVLT.printTree();
		System.out.println();
		
		
	}
}
</pre><pre name="code" class="java">

    原文作者:二叉查找树
    原文地址: https://blog.csdn.net/foryouB/article/details/45362089
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞