/**
* Objective: To achieve AVL
* Using arrays to simplify the code for the left and right son, but the mental difficulty is increased a lot, only suitable for the ACM template
* In fact, AVL in the ACM basically do not need to be treap replaced
* AVL generally only requires understanding of ideas, do not require writing code, because really annoying
*/
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <string>
#include <time.h>
#include <queue>
using namespace Std;
int COUNT; Number of distinct nodes in the statistics tree
int HEIGHT; The height of the statistic number
Data nodes
Class Dnode
{
Public
int data;
Dnode ():d ata (0) {};
Dnode (int D):d ata (d) {}
bool operator = (const Dnode &d) {
return data = d.data;
&NBSP}
bool operator = = (Const Dnode &d) {
return data = d.data;
&NBSP}
bool operator > (const dnode &d) {
return data > d.data;
&NBSP}
bool operator < (const dnode &d) {
return data < D.data;
&NBSP}
void Show () {
cout << Endl;
cout << "***************" << Endl;
cout << "data:" << data << Endl;
}
};
//treap node
Template<class t>
class avlnode{
Private:
int hgt; //Node height
Public:
t data;
int Count;
AVLNode<T> *son[2]; //0 is the left son, 1 is the right son
AVLNode<T> (T data):d ATA (data), COUNT (1) {
son[0] = son[1] = NULL;
&NBSP;&NBSP;HGT = 1;
}
int max (int a, int b) {return a > b a:b;}
void Show () {
Data.show ();
cout << "C hgt:" << this->height () << Endl;
cout << "L HGT:" << this->son[0]->height () << Endl;
cout << "R hgt:" << this->son[1]->height () << Endl;
cout << "Count:" << count << Endl;
cout << Endl;
}
int height () {
if (NULL = = this)
return 0;
Return _getheight (this);
}
int _getheight (avlnode<t> * cur) {
if (NULL = = cur)
return 0;
Return 1 + max (_getheight (cur->son[0)), _getheight (cur->son[1));
}
void SetHeight () {
HGT = _getheight (this);
}
};
AVL Tree
Here the T is the data type in the node
Template<class t>
Class avltree{
Private
avlnode<t> * ROOT; Root node
int hgt; The height of the tree
int size; Number of distinct nodes in the tree
void _insert (avlnode<t> *& cur, T data);
void _mid_travel (avlnode<t> *cur);
Hierarchy traversal
void _cengci_travel (avlnode<t> *cur);
Single rotation (left and right), the left is not meant to rotate left, but because the height of Zuozi's left son is too large
Contrary to Treap's rotating name
void _singleroate (avlnode<t> *& cur, int dir);
Double rotation (two times single rotation)
void _doubleroate (avlnode<t> *& cur, int dir);
int max (int a, int b) {
Return a > B? A:B;
}
Public
Avltree (): Root (NULL), HGT (0) {}
void Insert (const T & data);
void Mid_travel ();
int height () {
return Root->height ();
}
Hierarchy traversal
void Cengci_travel () {
_cengci_travel (root);
};
};
/************* Private Method Start **********************/
Template<class t>
void Avltree<t>::_insert (avlnode<t> *& cur, T data) {
if (NULL = = cur) {
cur = new avlnode<t> (data);
}else if (data = = Cur->data) {
cur->count++;
}else{
int dir = (data > Cur->data);
_insert (Cur->son[dir], data);
if (2 <= cur->son[dir]->height ()-cur->son[!dir]->height ()) {
bool LR = (data > Cur->data);
Lr? _singleroate (cur, dir): _doubleroate (cur, dir);
}
}
Cur->setheight ();
cout << "Set height:" << endl;
Cur->show ();
}
Template<class t>
void Avltree<t>::_mid_travel (avlnode<t> * cur) {
if (NULL!= cur) {
Find the subtree first.
_mid_travel (Cur->son[0]);
if (ABS (Cur->son[0]->height ()-cur->son[1]->height ()) >= 2)
{
Cur->show ();
}
_mid_travel (cur->son[1]);
}
}
Hierarchy traversal,
Output 0来 placeholder If the node is empty
Template<class t>
void Avltree<t>::_cengci_travel (avlnode<t> * cur) {
if (NULL = = cur)
Return
Queue<avlnode<t>*> Q;
Q.push (cur);
avlnode<t> *top = NULL;
queue<avlnode<t>*> tmp;
while (!q.empty ()) {
while (!q.empty ()) {
top = Q.front ();
Q.pop ();
if (NULL = top) {
Use # to represent the node is empty, #的后代还是 #
cout << ' # ' << ';
Tmp.push (top);
}else{
cout << top->data.data << "";
Tmp.push (Top->son[0]);
Tmp.push (top->son[1]);
}
}
BOOL flag = FALSE;
while (!tmp.empty ()) {
if (NULL!= tmp.front ())
Flag = true;
Q.push (Tmp.front ());
Tmp.pop ();
}
cout << Endl;
if (!flag)
Break
}
}
Single rotation, that is, only one rotation at a time
Dir = 0 o'clock, left-left rotation, or right-right rotation
Template<class t>
void Avltree<t>::_singleroate (avlnode<t> *& cur, int dir) {
avlnode<t> *& k2 = cur, * k1 = k2->son[dir]; K2 must be a reference
K2->son[dir] = k1->son[!dir];
K1->son[!dir] = K2;
K2 = K1;
K2->setheight ();
K1->setheight ();
}
Double rotation, that is, two times single rotation
Dir = 0 is the left or right case;
Template<class t>
void Avltree<t>::_doubleroate (avlnode<t> *& cur, int dir) {
_singleroate (Cur->son[dir],!dir);
_singleroate (cur, dir);
}
/************* public Method (interface) Start **********************/
Template<class t>
void Avltree<t>::insert (const T & data) {
_insert (root, data);
}
Template<class t>
void Avltree<t>::mid_travel () {
_mid_travel (root);
}
int main () {
avltree<dnode>* AVLT = new avltree<dnode> ();
const int num = 30;
for (int i = 0; i < num; i++) {
Dnode * d = new Dnode (i);
Avlt->insert (*D);
}
cout << "************* in sequence traversal ***************" << Endl;
Avlt->mid_travel ();
cout << "************** in sequence traversal end **********" << Endl;
cout << "************* level traversal start ***************" << Endl;
Avlt->cengci_travel ();
cout << "************** level traversal end **********" << Endl;
cout << "The height of the tree is:" << avlt->height () << Endl;
return 0;
}