您的位置:首页 > 其它

平衡二叉树DSW算法

2016-09-27 11:15 295 查看
#include<iostream>
#include<stdlib.h>
#include<math.h>

using namespace std;
class Node{
public:
int el;
Node *left,*right;
Node(){
left=0;right=0;
}
Node(int data){
el = data;left=0;right=0;
}
};
class Tree{
public:
Node *root;
Tree(){
root=0;size=0;
}
Tree(int el){
root=new Node(el);size=1;
}
void insert(int el){
Node *ins = new Node(el),*tmp=root,*par;
if(tmp==0){
root = ins;
size++;
return;
}
while(tmp!=0){
par = tmp;
if(tmp->el>el)tmp = tmp->left;
else tmp = tmp->right;
}
if(par->el>el)
par->left = ins;
else
par->right = ins;
size++;
}

//  转换成右链
void creatBackbone(){
Node *Gr=0,*par=root,*ch=0;
while(par!=0){
ch = par->left;
if(ch!=0){
rotateRight(Gr,par,ch);
par=ch;
}else{
Gr=par;
par=par->right;
}
// 旋转过程中,如果是绕根节点的右节点旋转时要将根节点置为原根节点的右节点
if(Gr==0)root = ch;
}
}
void rotateRight(Node *Gr,Node *par,Node *ch){

if(Gr!=0)Gr->right=ch;
par->left=ch->right;
ch->right=par;
}
// 平衡二叉树
void creatPerfectTree(){
int n = size;
int m = (1<<((int)(log10(n+1)/log10(2))))-1;
int i;
Node *Gr=0,*tmp;
if(size<3)return;printf("%d\n",m);
for(i=0,Gr=root;i<n-m;i++){
if(i==0){
// 此处Gr是旋转时被绕的节点的祖父节点,下边以Gr->right传引用方便旋转函数赋值操作
Gr = Gr->right;
rotateLeft(root);
}else if(Gr&&Gr->right){
// 提前保存下次绕点的祖父节点,旋转后它们之间关系被破坏
tmp = Gr->right->right;
rotateLeft(Gr->right);
Gr = tmp;
}
}
while(m>1){
m = m/2;
for(i=0,Gr=root;i<m;i++){
if(i==0){
Gr = Gr->right;
rotateLeft(root);
}else if(Gr&&Gr->right){
tmp = Gr->right->right;
rotateLeft(Gr->right);
Gr = tmp;
}
}
}
}
void rotateLeft(Node *&Gr){
if(!Gr) return;
Node *par = Gr->right;
if(!par)return;
Node *ch  = par->right;
Gr->right=par->left;
par->left=Gr;
Gr = par;
}
private:
int size;
};
int main(){

int a[] = {0,3,4,5,6,1,2,7,11,12,8,9,10,13,14};
int i;
Tree *tree = new Tree();
for(i=0;i<15;i++){
tree->insert(a[i]);
}
tree->creatBackbone();
tree->creatPerfectTree();
return 0;
}


  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: