Untitled
unknown
plain_text
2 years ago
9.5 kB
10
Indexable
public class AVL {
Node root ;
public class Node {
private int data; // info
private int height; // height of the subtree
private int size ; // number of nodes in subtree
private Node left; // left subtree
private Node right; // right subtree
public Node(int data, int height, int size) {
this.data = data;
this.height = height;
this.size = size;
}
}
public boolean isEmpty() {
return root == null;
}
// size
public int size(Node x) {
return x == null ? 0 : x.size;
}
public int size() {
return size(root);
}
// lấy chiều cao
private int height(Node x) {
return x == null ? 0 : x.height;
}
public int height() {
return height(root);
}
// Search + check if present
private Node get(Node x, int data) {
if (x == null) return null;
int cmp = Integer.compare(data, x.data);
if (cmp < 0) return get(x.left, data);
else if (cmp > 0) return get(x.right, data);
else return x;
}
public boolean contains(int data) {
return get(root,data) != null;
}
// Tìm hệ số cân bằng
private int balanceFactor(Node x) {
return height(x.left) - height(x.right);
}
// Quay trái:
/*
* 3 6
* * ---> * *
* 6 3 9
* * * *
* 5 9 5
* */
private Node rotateLeft(Node top) {
Node mid = top.right;
top.right = mid.left;
mid.left = top;
mid.size = top.size;
top.size = 1 + size(top.left) + size(top.right);
top.height = 1 + Math.max(height(top.left), height(top.right));
mid.height = 1 + Math.max(height(mid.left), height(mid.right));
return mid;
}
// Quay phải: ngược lại
private Node rotateRight(Node top) {
Node mid = top.left;
top.left = mid.right;
mid.right = top;
mid.size = top.size;
top.size = 1 + size(top.left) + size(top.right);
top.height = 1 + Math.max(height(top.left), height(top.right));
mid.height = 1 + Math.max(height(mid.left), height(mid.right));
return mid;
}
// Cây cân bằng khi hiệu chiều cao 2 chị em tối đa là 1 -> sai thì xoay: 4 trường hợp:
private Node balance(Node x) {
// hiệu < -1 (3-5) ~ cây nghiêng phải: Right -> Right-Right + Right-Left
if (balanceFactor(x) < -1) {
if (balanceFactor(x.right) > 0) {
x.right = rotateRight(x.right);
}
x = rotateLeft(x);
}
// hiệu > 1 (5-3) ~ cây nghiêng trái: Left -> Left - right + left - left
else if (balanceFactor(x) > 1) {
if (balanceFactor(x.left) < 0) {
x.left = rotateLeft(x.left);
}
x = rotateRight(x);
}
return x;
}
// MIN and MAX:
public Node min(Node x) {
if (x.left == null) return x;
return min(x.left);
}
public Node max(Node x) {
if (x.right == null) return x;
return max(x.right);
}
// INSERT
private Node insert(Node x, int data) {
// Leaf: new node: data, h = 1, size = 1;
if (x == null) return new Node(data, 1, 1);
int cmp = Integer.compare(data, x.data);
if (cmp < 0) {
x.left = insert(x.left, data);
}
else if (cmp > 0) {
x.right = insert(x.right, data);
}
else {
x. data = data;
return x;
}
x.size = 1 + size(x.left) + size(x.right);
x.height = 1 + Math.max(height(x.left), height(x.right));
return balance(x);
}
public void insert(int data){
root = insert(root, data);
}
// Delete: search + xoá thật
// Hàm phụ trợ: xoá min of subtree 'x'-> gọi sau khi clone: nút cần xoá = minRight -> clear minRight
// @param Node x...chính là cây con phải của nút cần xoá:
private Node deleteMin(Node x) {
if (x.left == null) return x.right;
x.left = deleteMin(x.left);
x.size = 1 + size(x.left) + size(x.right);
x.height = 1 + Math.max(height(x.left), height(x.right));
return balance(x);
}
private Node delete(Node x, int data) {
// Search
int cmp = Integer.compare(data, x.data);
if (cmp < 0) {
x.left = delete(x.left, data);
}
else if (cmp > 0) {
x.right = delete(x.right, data);
}
// found
else {
if (x.left == null)
return x.right;
else if (x.right == null)
return x.left;
// đủ 2 con
else {
Node temp = x;
x = min(temp.right);
x.right = deleteMin(temp.right);
x.left = temp.left;
}
}
x.size = 1 + size(x.left) + size(x.right);
x.height = 1 + Math.max(height(x.left), height(x.right));
return balance(x);
}
public void delete(int data){
if (!contains(data)) return;
root = delete(root, data);
}
/// FLOOR: find x <= K, nhỏ hơn hoặc bằng K ~ ưu tiên cao hơn
private Node floor(Node x, int data) {
if (x == null) return null;
int cmp = Integer.compare(data, x.data);
if (cmp < 0) return floor(x.left,data);
if (cmp == 0) return x;
Node temp = floor(x.right,data);
return temp == null ? x : temp;
}
public int floor(int data){
Node x = floor(root, data);
return x == null ? null : x.data;
}
// Ceiling: find x >= K (ưu tiên thấp hơn)
private Node ceiling(Node x, int data) {
if (x == null) return null;
int cmp = Integer.compare(data, x.data);
if (cmp > 0) return ceiling(x.right,data);
if (cmp == 0) return x;
Node temp = ceiling(x.left,data);
return temp == null ? x : temp;
}
public int ceiling(int data){
Node x = ceiling(root, data);
return x == null ? null : x.data;
}
// Kth smallest : tính từ 0 -> 5th ~ select(4)
private Node select(Node x, int Kth) {
if (x == null) return null;
int t = size(x.left); // số lượng < x ~ rankASC(x) in subtree x
if (t > Kth) return select(x.left, Kth);
else if (t < Kth) return select(x.right, Kth - t - 1);
else return x;
}
public int select(int Kth){
if (Kth < 0 || Kth >= size()) return -1;
return select(root, Kth).data;
}
public int selectDSC(int Kth){
int k = size() - (Kth+1);
if (k < 0 || k >= size()) return -1;
return select(root,k).data;
}
// Rank(data) -> chính xác từ 1 -> N
public int rankDSC(int data){
return size() + 1 - rankASC(data);
}
public int rankASC(int data) {
return rankASC(root,data,0);
}
private int rankASC(Node x, int data, int currentRank) {
if(x==null) return currentRank;
int cmp = Integer.compare(data, x.data);
if(cmp>=0){
if(x.left == null)
currentRank += 1;
else
currentRank += 1 + size(x.left);
return rankASC(x.right,data,currentRank);
}else
return rankASC(x.left,data,currentRank);
}
// tính từ 0 -> cần chỉnh ở hàm public
private int rankASC1(Node x, int data) {
if(x==null) return 0;
int cmp = Integer.compare(data, x.data);
if(cmp > 0) return 1 + size(x.left) + rankASC1(x.right,data);
else if (cmp < 0) return rankASC1(x.left,data);
else return size(x.left);
}
// Count number of element in range between 2 nodes include 2 nodes
public int sizeIN(int low, int high) {
// return contains(high)? rankASC(high) - rankASC(low) + 1 : rankASC(high) - rankASC(low);
return rankASC(high) - rankASC(low) + 1 ;
}
public static void main(String[] args) {
AVL avl = new AVL();
avl.insert(100);
avl.insert(200);
avl.insert(300);
avl.insert(820);
avl.insert(510);
avl.insert(282);
avl.insert(150);
avl.insert(182);
//avl.delete(300);
// for(int i = 0; i< avl.size();i++ ) // từ 1 -> N
// System.out.println(avl.selectDSC(i));
// System.out.println();
// for(int i = 0; i< avl.size();i++ ) // từ 1 -> N
// System.out.println(avl.select(i));
// System.out.println(avl.rankDSC(100));
// System.out.println(avl.rankDSC(150));
// System.out.println(avl.rankDSC(182));
// System.out.println(avl.rankDSC(200));
// System.out.println(avl.rankDSC(282));
// System.out.println(avl.rankDSC(300));
// System.out.println(avl.rankDSC(510));
System.out.println(avl.sizeIN(100,800));
System.out.println(avl.sizeIN(100,820));
//System.out.println(avl.root.data);
}
}
Editor is loading...