1.二叉树
1.定义
二叉树是一种每个结点至多只有两个子树(左子树,右子树),并且二叉树的子树左右之分不能颠倒。
2.性质
(1)在二叉树的第i层,最多有2^(i-1)个结点;
(2)深度为k的二叉树最多有(2^k)-1个结点;
3.满二叉树
除了叶子结点外的每个结点都有左右两个子树。
2.java实现二分搜索树
1.二分搜索树特点
- 二分搜索树是一个动态数据结构;
- 二分搜索树也是一个二叉树;
- 二分搜索树的每个结点的值都大于其左子树上的所有结点的值,小于其右子树上的所有结点的值;
- 存储的元素必须有可比较性,必须实现Comparable接口,或者使用额外的比较器实现;
- 每一颗子树也是二分搜索树;
- 二分搜索树具有唯一的根节点,同时,在二叉树中的最底下是它的叶子结点。
- 二分搜索树天然的具有递归特性:(1)每个结点的左子树也是二叉树;(2)每个结点的右子树也是二叉树。
2.java实现
public class BST<T extends Comparable<T>> {
private class Node<T extends Comparable<T>>{
T ele;
Node left,right;//左右子树
public Node(T ele){
this.ele = ele;
this.left = null;
this.right = null;
}
}
//根节点
private Node root;
private int size;
public BST(){
root = null;
size = 0;
}
//获取长度
public int getSize(){
return size;
}
//判断是否为空
public boolean isEmpty(){
return size == 0;
}
//添加元素
public void add(T ele){
root = addEle(root,ele);
}
private Node addEle(Node node,T e){
if(node == null){
size++;
return new Node(e);
}
if(node.ele.compareTo(e) > 0){
node.left = addEle(node.left,e);
}else if(node.ele.compareTo(e) < 0){
node.right = addEle(node.right,e);
}
return node;
}
//判断二分搜索树是否含有指定元素
public boolean contains(T ele){
return containsEle(root,ele);
}
private boolean containsEle(Node node,T e){
if(node == null){
return false;
}
if(node.ele.compareTo(e) > 0){
return containsEle(node.left,e);
}else if(node.ele.compareTo(e) < 0){
return containsEle(node.right,e);
}else {
return true;
}
}
//二叉树遍历(前序遍历)
/**
* 1.当前结点
* 2.左子树
* 3.右子树
* @return
*/
public String preOrder(){
if(root == null){
return null;
}
StringBuffer result = new StringBuffer();
preOrderTree(root,result);
return result.toString();
}
private void preOrderTree(Node node,StringBuffer result){
if(node == null){
return;
}
//1.当前结点
result.append(node.ele+"---");
//2.左子树
preOrderTree(node.left,result);
//右子树
preOrderTree(node.right,result);
}
//后序遍历
/**
* 1.左子树
* 2.右子树
* 3.当前结点
* @return
*/
public String subOrder(){
if(root == null){
return null;
}
StringBuffer result = new StringBuffer();
subOrderTree(root,result);
return result.toString();
}
private void subOrderTree(Node node,StringBuffer result){
if(node == null){
return;
}
//左子树
subOrderTree(node.left,result);
//右子树
subOrderTree(node.right,result);
//当前结点
result.append(node.ele+"---");
}
//中序遍历
/**
* 1.左子树
* 2.当前结点
* 3.右子树
*/
public String middleOrder(){
if(root == null){
return null;
}
StringBuffer result = new StringBuffer();
middleOrderTree(root,result);
return result.toString();
}
private void middleOrderTree(Node node,StringBuffer result){
if(node == null){
return;
}
//左子树
middleOrderTree(node.left,result);
//当前结点
result.append(node.ele+"---");
//右子树
middleOrderTree(node.right,result);
}
//层序遍历
public String levelOrder(){
StringBuffer result = new StringBuffer();
Queue<Node> queue = new LinkedList<>();
queue.offer(root);
while (!queue.isEmpty()){
Node node = queue.poll();
result.append(node.ele+"---");
if(node.left != null){
queue.offer(node.left);
}
if(node.right != null){
queue.offer(node.right);
}
}
return result.toString();
}
//查找二分搜索树最小值
public Node findMinNode(){
if(root == null){
return null;
}
Node cur = root;
while (cur.left != null){
cur = cur.left;
}
return cur;
}
//删除最小值
public T removeMin(){
Node delNode = findMinNode();
if(delNode == null){
return null;
}
if(delNode == root && root.right != null){
size--;
root = root.right;
}else if(delNode == root && root.right == null){
size--;
root = null;
}else {
removeMinNode(root);
}
return (T)delNode.ele;
}
private Node removeMinNode(Node node){
if(node == null){
return null;
}
if(node.left != null){
node.left = removeMinNode(node.left);
}else if(node.left == null && node.right != null){
size--;
node = node.right;
}else if(node.left == null && node.right == null){
size--;
node = null;
}
return node;
}
//查找二分搜索树最大值
public Node findMaxNode(){
if(root == null){
return null;
}
Node cur = root;
while (cur.right != null){
cur = cur.right;
}
return cur;
}
//删除最大值
public T removeMax(){
Node delNode = findMaxNode();
if(delNode == null){
return null;
}
if(delNode == root && root.left != null){
size--;
root = root.left;
}else if(delNode == root && root.left == null){
size--;
root = null;
}else {
removeMaxNode(root);
}
return (T)delNode.ele;
}
private Node removeMaxNode(Node node){
if(node == null){
return null;
}
if(node.right != null){
node.right = removeMaxNode(node.right);
}else if(node.right == null && node.left != null){
size--;
node = node.left;
}else if(node.right == null && node.left == null){
size--;
node = null;
}
return node;
}
}
测试:
public void BSTtest(){
BST<Integer> bst = new BST<>();
int arr[] = {1,3,4,2,5};
for(int i = 0;i<arr.length;i++){
bst.add(arr[i]);
}
System.out.println("tree size:"+bst.getSize());//tree size:5
//System.out.println(bst.isEmpty());//false
//System.out.println(bst.preOrder());//1---3---2---4---5---
//System.out.println(bst.contains(1));//true
//System.out.println(bst.subOrder());//2---5---4---3---1---
//System.out.println(bst.middleOrder());//1---2---3---4---5---
//System.out.println(bst.levelOrder());//1---3---2---4---5---
System.out.println(bst.removeMin());//1
System.out.println(bst.middleOrder());//2---3---4---5---
System.out.println("tree size:"+bst.getSize());//4
System.out.println(bst.removeMax());//5
System.out.println(bst.middleOrder());//2---3---4---
System.out.println("tree size:"+bst.getSize());//tree size:3
}