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);
}
}