数据结构与算法_04【二分搜索树】

1、树结构简介
树结构本身是一种天然的组织结构,将数据使用树结构存储后,会大幅高效率。
树:元素与元素之间存在一对多的关系 层次关系
2、什么是二叉树
和链表一样,动态数据结构
class Node{
E e;
Node left; //左孩子
Node right; //右孩子
}
(1)、多叉树(多个子结点)
(2)、二叉树具有唯一根节点
(3)、二叉树中每个结点最多有两个孩子,没有孩子的结点称之为叶子结点
(4)、二叉树中每个结点最多有一个父亲结点,根节点没有父亲结点
(5)、二叉树具有天然递归结构,每个结点的左子树或右子树,也是一个二叉树

(6)、二叉树不一定是“满”的
(7)、极端的左或右都是二叉树,只不过退化成了线性表,这种情况称之为不平衡二叉

在这里插入图片描述
(8)、一个结点也叫二叉树,无非左右孩子都为null,null 空也是二叉树
3、二叉树怎么存?
动态数组 动态链表
如果用动态数组存一个深度为h的二叉树 最多需要 2^h-1
每一层最多2^(h-1)个节点
如果此时的二叉树不是一个平衡二叉树 那么用动态数组存会有很多空间浪费
平衡:
满二叉树:叶子节点的深度差为0 且最后一层全是叶子结点
完全二叉树:是按照每一层从左到右填充节点 叶子节点的深度差<=1
满二叉树一定是完全二叉树
完全二叉树不一定是满二叉树
4、什么是二分搜索树
二分搜索树是二叉树
对于二分搜索树的每个结点的值而言
(1)大于其左子树的所有结点的值
(2)小于其右子树的所有结点的值
(3)其每一个子树也是二分搜索树
在这里插入图片描述
(4)二分搜索树中所存储的元素必须具有可比较性!实现Comparable接口
(5)不包含重复元素
二分搜索树的功能实现

package 二分搜索树;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;
**//定义类**
public class BinarySearchTree<E extends Comparable<E>> { // BST
**//定义结点(内部类)**
	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 BinarySearchTree() {
		root = null;
		size = 0;
	}

	**// 获取树中元素的个数**
	public int size() {
		return size;
	}

	**// 判断树是否为空**
	public boolean isEmpty() {
		return size() == 0;
	}

	**// 将元素e添加到树中**
	public void add(E e) {
		// 迭代实现
		/*
		 * if(size()==0){ root=new Node(e); size++; } Node p=root; while(true){
		 * if(e.compareTo(p.e)==0){ return; }else if(e.compareTo(p.e)>0){
		 * if(p.right!=null){ p=p.right; }else{ p.right=new Node(e); size++;
		 * return; } }else{ if(p.left!=null){ p=p.left; }else{ p.left=new
		 * Node(e); size++; return; } } }
		 */
		root = add(root, e);
	}

	// 以node为当前树的根节点,添加元素e并返回该树的根
	private Node add(Node node, E e) {
		if (node == null) {
			size++;
			return new Node(e);
		}
		if (e.compareTo(node.e) > 0) {
			node.right = add(node.right, e);	//在右子树中添加元素e并且连接在右子树的后面
		} else if (e.compareTo(node.e) < 0) {
			node.left = add(node.left, e);
		}
		return node;
	}

	**// 查找元素e是否存在于树中**
	public boolean contains(E e) {
		// 迭代实现
		/*
		 * if(size()==0){ return false; } Node p=root; while(p!=null){
		 * if(e.compareTo(p.e)>0){ p=p.right; }else if(e.compareTo(p.e)<0){
		 * p=p.left; }else{ return true; } } return false;
		 */
		return contains(root, e);
	}

	**// 查找以node为根节点的树是否包含元素e**
	private boolean contains(Node node, E e) {
		if (node == null) {
			return false;
		}
		if (e.compareTo(node.e) > 0) {
			return contains(node.right, e);
		} else if (e.compareTo(node.e) < 0) {
			return contains(node.left, e);
		} else {
			return true;
		}
	}

	**// 中序遍历 preOrder前序 postOrder后序**
	public void inOrder() {
		ArrayList<E> list = new ArrayList<E>();
		inOrder(root, list);
		System.out.println(list);
	}

	private void inOrder(Node node, ArrayList<E> list) {
		if (node == null) {
			return;
		}
		inOrder(node.left, list);
		list.add(node.e);
		inOrder(node.right, list);
	}

	**// 层序遍历 广度优先遍历**
	public void levelOrder() {
		ArrayList<E> list = new ArrayList<E>();
		**// 用辅助队列实现层序遍历**
		Queue<Node> queue = new LinkedList<Node>();
		queue.add(root);
		while (!queue.isEmpty()) {
			Node cur = queue.poll();
			list.add(cur.e);
			if (cur.left != null) {
				queue.add(cur.left);
			}
			if (cur.right != null) {
				queue.add(cur.right);
			}
		}
		System.out.println(list);
	}
	/*
	41
		22
			15
				13
			33
				37
		58
			50
				42
				53
					null
					null
		58
	41
			33
		22
			15
	 */
	@Override
	public String toString() {
		StringBuilder sb=new StringBuilder();
		generateBSTString(root,0,sb);
		return sb.toString();
	}
	private void generateBSTString(Node node, int level,
			StringBuilder sb) {
		if(node==null){
			sb.append(generateDepthString(level)+"null\n");
			return;
		}
		generateBSTString(node.left, level+1, sb);
		sb.append(generateDepthString(level)+node.e+"\n");
		generateBSTString(node.right, level+1, sb);
	}
	private String generateDepthString(int level) {
		StringBuilder sb=new StringBuilder();
		for(int i=0;i<level;i++){
			sb.append("--");
		}
		return sb.toString();
	}
	**// 获取最小值**
	public E minmum(){
		if(size()==0){
			throw new IllegalArgumentException("Tree is empty!");
		}
		return minmun(root).e;
	}
	// **以node为根节点 查找该树中的最小值**
	private Node minmun(Node node){
		if(node.left==null){
			return node;
		}
		return minmun(node.left);
	}
	**// 获取最大值**
	public E maxmun(){
		if(size()==0){
			throw new IllegalArgumentException("Tree is empty!");
		}
		return maxmum(root).e;
	}
	private Node maxmum(Node node) {
		if(node.right==null){
			return node;
		}
		return maxmum(node.right);
	}
	**// 删除最小值**
	public E removeMin(){
		E e=minmum();
		root=removeMin(root);
		return e;
	}
	**// 以node为根节点的二分搜索树,在删除最小值之后并返回新树的根**
	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;
	}
	**// 删除最大值**
	public E removeMax(){
		E e=maxmun();
		root=removeMax(root);
		return e;
	}
	private Node removeMax(Node node){
		if(node.right==null){
			Node leftNode=node.left;
			node.left=null;
			size--;
			return leftNode;
		}
		node.right=removeMax(node.right);
		return node;
	}
	public void remove(E e){
		root=remove(root,e);
	}
	**// 以node为根 删除指定元素e之后 返回新树的根**
	private Node remove(Node node,E e){
		if(node==null){
			return null;
		}
		if(e.compareTo(node.e)>0){
			node.right=remove(node.right,e);
			return node;
		}else if(e.compareTo(node.e)<0){
			node.left=remove(node.left,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=minmun(node.right);
			successor.right=removeMin(node.right);
			successor.left=node.left;
			node.left=node.right=null;
			return successor;
		}
	}
}

Main函数

package 二分搜索树;
public class Main {
	public static void main(String[] args) {
		BinarySearchTree<Integer> bst=new BinarySearchTree<>(); 
		bst.add(8);
		bst.add(6);
		bst.add(9);
		bst.add(7);
		bst.add(5);
		bst.add(10);
		bst.inOrder();
		System.out.println("size="+bst.size());
		System.out.println(bst);
		bst.remove(8);
		System.out.println("size="+bst.size());
		bst.inOrder();
		System.out.println(bst);
	}
}

猜你喜欢

转载自blog.csdn.net/weixin_44561640/article/details/89220269