恋上数据结构与算法第一季笔记—— 平衡搜索二叉树
Posted Johnny*
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了恋上数据结构与算法第一季笔记—— 平衡搜索二叉树相关的知识,希望对你有一定的参考价值。
平衡
理想平衡
改进
平衡二叉搜索树
AVL 树
平衡对比
AVLTree
继承结构
添加导致的失衡
右旋转
左旋转
LR —— RR左旋,LL右旋
AVLTree
package trees;
public class AVLTree<E> extends BST<E> {
}
//默认只有无参的构造方法
AVLTree<Integer> avl = new AVLTree<>();
添加了以下构造方法才能使用
public AVLTree(){
this(null);
}
public AVLTree(Comparator comparator){
//调用父类的构造方法
super(comparator);
}
//
AVLTree<Integer> avl2 = new AVLTree<>(new Comparator() {
@Override
public int compare(Object o1, Object o2) {
return 0;
}
});
由于Node中没有无参构造方法,所以AVLNode必须
class AVLNode extends Node{
}
删除
删除导致的失衡
LL
RR 右旋
LR
注意高度变化对祖先的节点的影响
RL
实现
BinaryTree
package trees;
import printer.BinaryTreeInfo;
import java.util.LinkedList;
import java.util.Queue;
@SuppressWarnings("unchecked")
public class BinaryTree<E> implements BinaryTreeInfo{
//元素数量
protected int size;
//二叉树根节点
protected Node<E> root;
/**
* 清空所有元素
*/
public void clear (){
root = null;
size = 0;
}
public void preOrder(Visitor visitor){
if(visitor == null ) return;
if( root != null) preOrderTraverse(root, visitor);
}
/**
* 前序遍历(根左右)
* @param root
*/
private void preOrderTraverse(Node<E> root, Visitor<E> visitor){
if( root == null || visitor.stop) return ;
visitor.stop = visitor.visit(root.element);
preOrderTraverse(root.left, visitor);
preOrderTraverse(root.right, visitor);
}
public void inOrder(Visitor<E> visitor){
if(visitor == null ) return;
if( root != null) inOrderTraverse(root, visitor);
}
/**
* 中序遍历(左根右)
* @param root
*/
private void inOrderTraverse(Node<E> root, Visitor<E> visitor){
if( root == null || visitor.stop) return ;
inOrderTraverse(root.left, visitor);
if( visitor.stop ) return;
visitor.stop = visitor.visit(root.element);
inOrderTraverse(root.right, visitor);
}
public void postOrder(Visitor<E> visitor){
if(visitor == null ) return;
if( root != null) postOrderTraverse(root, visitor);
}
/**
* 后序遍历(左右根)
* @param root
*/
private void postOrderTraverse(Node<E> root, Visitor<E> visitor){
if( root == null || visitor.stop) return ;
postOrderTraverse(root.left, visitor);
postOrderTraverse(root.right, visitor);
if (visitor.stop) return;
visitor.stop = visitor.visit( root.element); //将节点通过visit接口传递给外面处理
}
public void levelOrderTraverse(Visitor<E> visitor){
if( visitor == null ||root == null ) return;
Queue<Node<E> > q = new LinkedList<>();
q.offer( root ); //根节点入队
while( ! q.isEmpty() ){
//取出队首 并访问
Node<E> node = q.poll();
//将node的element元素通过Visitor接口的visit方法传递到外面出去
//同时visit方法有返回值返回
if ( visitor.visit(node.element) ) return;
//将node左右孩子入队
if( node.left != null ) q.offer(node.left);
if( node.right != null ) q.offer(node.right);
}
}
public static abstract class Visitor<E>{
boolean stop;
/**
* 如果返回true 则代表停止遍历
* @param element
* @return
*/
protected abstract boolean visit(E element);
}
public int height(){
if( root == null) return 0;
// return heightReverse(root);
return heightLevelOrder();
}
protected Node<E> createNode(Node<E> parent,E element) {
return new Node<E>( parent,element);
}
/**
* 判断一颗树是否是完全二叉树
* @return
*/
public boolean isCompelete(){
if( root == null ) return false; // 空树不是完全二叉树
//层次遍历
Queue<Node<E>> q = new LinkedList<>();
q.offer( root );
boolean leaf = false;
while( !q.isEmpty() ){
Node<E> node = q.poll();
if( leaf && ! node.isLeaf() ) return false;
if( node.hashTwoChildren() ){//度为2的节点
q.offer(node.left);
q.offer(node.right);
}else if(node.left == null && node.right != null ){//到这:则节点度可能为0 也可能为1
return false;
}else{//此后所有的节点都必须是叶子节点
leaf = true;
}
}
return true;
}
/**
* 递归方式计算树的高度
* @param node
* @return
*/
private int heightReverse(Node node){
if( node == null ) return 0;
return 1 + Math.max( heightReverse(node.left), heightReverse(node.right) );
}
/**
* 层次遍历计算树的高度
* @return
*/
private int heightLevelOrder(){
Queue<Node<E>> q = new LinkedList<>();
q.offer(root);
int levelSize = 1; //当前层的节点个数
int height = 0;
while( ! q.isEmpty() ){
Node<E> node = q.poll();
levelSize --; //每从队列中取出节点 当前层节点数就减一
if( node.left != null ) q.offer(node.left);
if( node.right != null ) q.offer(node.right);
if( levelSize == 0){//当前层访问完 下一层的节点数为队列元素个数
levelSize = q.size();
height ++;
}
}
return height;
}
/**
* 返回一个节点的前驱
* @param node
* @return
*/
protected Node<E> predecessor(Node node){
if( node == null ) return null;
Node<E> p = node.left;
//node.left != null
// 寻找node.left.right.right…… 一直到
if( p != null){
while( p.right != null ) p = p.right;
return p;
}
//node.left == null && node.parent!=null
//一直找到 node = node.parent.right
while( node.parent != null && node != node.parent.right ){
node = node.parent;
}
//node.parent == null || node == node.parent.right
return node.parent;
}
/**
* 返回一个节点的后继节点
* @param node
* @return
*/
protected Node<E> successor(Node node){
if( node == null ) return null;
Node<E> p = node.right;
//node.left != null
// 寻找node.right.left.left…… 一直到
if( p != null){
while( p.left != null ) p = p.left;
return p;
}
//node.left == null && node.parent!=null
//一直找到 node = node.parent.left
while( node.parent != null && node != node.parent.left ){
node = node.parent;
}
//node.parent == null || node == node.parent.left
return node.parent;
}
@Override
public Object root() {
return this.root;
}
@Override
public Object left(Object node) {
return ((Node<E>) node).left;
}
@Override
public Object right(Object node) {
return ((Node<E>) node).right;
}
@Override
public Object string(Object node) {
return null;
}
//内部类且修饰符protected
// protected:该包下及其子类都可以访问
protected static class Node<E> {
E element;
Node<E> left;
Node<E> right;
Node<E> parent;
public Node(Node<E> parent, E element) {
this.parent = parent;
this.element = element;
}
public Node(){}
public boolean hashTwoChildren() {
return this.left != null && this.right != null;
}
public boolean isLeaf() {
return this.left == null && this.right == null;
}
public boolean isLeftChild(){ return parent != null && parent.left == this; }
public boolean isRightChild(){ return parent != null && parent.right == this; }
}
}
BST
package trees;
import java.util.Comparator;
public class BST<E> extends BinaryTree<E> {
//比较器:由外部定义比较规则,并将比较器传进来使用
private Comparator<E> comparator;
//带比较器的构造方法
public BST(Comparator<E> comparator){
this.comparator = comparator;
}
//不带比较器则默认使用comparable的比较方法
public BST(){
this(null);
}
@Override
public Object string(Object node) {
Node<E> newNode = ((Node<E>) node);
E parentElement = newNode.parent == null ? null: newNode.parent.element;
return newNode.element+"_("+parentElement+")";
}
@Override
public String toString() {
if( root == null ) return null;
StringBuilder sb = new StringBuilder();
toString(root, sb,"");
return sb.toString();
}
/**
* 前序遍历展示树形结构
* @param node
* @param sb 整个树遍历的记录
* @param prefix 记录当前节点的前缀
*/
private void toString(Node<E> node, StringBuilder sb,String prefix){
if( node == null ) return;
sb.append(prefix).append(node.element).append("\\n");
toString(node.left, sb, prefix+"【L】");
toString(node.right, sb, prefix +"【R】");
}
/**
* 元素数量
* @return
*/
public int size(){
return size;
}
/**
* 二叉搜索树是否为空
* @return
*/
public boolean isEmpty(){
return size == 0;
}
public void add( E element){
//二叉树树不允许节点为空 插入前先判断
elementNotNullChck(element);
//添加第一个节点
if( root == null){
root = createNode(null, element);
size ++;
//添加节点后调整为AVL二叉树
afterAdd(root);
return ;
}
int cmp = 0;
Node<E> node = root;
Node<E> parent 恋上数据结构与算法第一季笔记——红黑树