ADS刚好学了AVL树,现在简单地写了有关AVL树建立的一点代码。
首先了解一下AVL树,概念性的东西不再细讲了,主要讲一下自己初写代码遇到的一些问题和疑惑,共勉。
旋转
其实AVL树最重要的操作也就是旋转了,共分为LL、RR、LR、RL四种,其实就是可分为两种,LL、RR为一组,LR、RL为一组。前者是插入最小元素或最大元素的时候,在这里我用全局的min和max判断实现,每次插入后刷新,而后者则只需要判断是插入到根节点左边还是右边即可。
其次是失衡节点的判断,采用了高度函数而未在数据结构中写入,主要是有点懒,不想在旋转后再改,然后插入过程中先插入后旋转最后返回。这样保证旋转的必定是离插入节点最近的节点。
代码如下
#include<stdio.h>
#include<stdlib.h>
//树:包括数据、左右子树
typedef struct node{
int num;
struct node *left,*right;
}T;
//分别存储最左边节点、最右边节点以及根节点数据
int min,max,orin;
T *insert(T *tree,int t);
T *Lrot(T *tree);
T *Rrot(T *tree);
int GetH(T *tree);
int main(){
int N,i,t;
T *tree = NULL;
scanf("%d",&N);
for(i = 0;i<N;i++){
scanf("%d",&t);
if(i==0) min = max =t;
else orin = tree->num;
tree = insert(tree,t);
if(t<min) min = t;
else if(t>max) max = t;
}
printf("%d",tree->num);
}
//插入函数
T *insert(T *tree, int t){
if(tree==NULL){
tree=(T*)malloc(sizeof(T));
tree->num = t;
tree->left = tree->right = NULL;
}
else if(t<tree->num){
tree->left=insert(tree->left,t);
}
else{
tree->right=insert(tree->right,t);
}
//实现二叉搜索树
if(t<min){
if((GetH(tree->left)-GetH(tree->right))>1){
tree = Lrot(tree);
}
}
//定义的LL旋转
else if(t>max){
if((GetH(tree->right)-GetH(tree->left))>1){
tree = Rrot(tree);
}
}
//定义的RR旋转
else{
if(t<orin){
if((GetH(tree->left)-GetH(tree->right))>1){
tree->left = Rrot(tree->left);
tree = Lrot(tree);
}
}
//定义的RL旋转
else{
if((GetH(tree->right)-GetH(tree->left))>1){
tree->right = Lrot(tree->right);
tree = Rrot(tree);
}
}
//定义的LR旋转
}
//先完成树的插入和旋转再返回
return tree;
}
//高度测量
int GetH(T *tree){
if(tree==NULL) return 0;
else return (GetH(tree->left)>GetH(tree->right))?(GetH(tree->left)+1):(GetH(tree->right)+1);
}
//定义的右旋
T *Rrot(T *tree){
T *m;
m = (T*)malloc(sizeof(T));
m = tree->right;
tree->right = m->left;
m->left=tree;
return m;
}
//定义的左旋
T *Lrot(T *tree){
T *m;
m = (T*)malloc(sizeof(T));
m = tree->left;
tree->left = m->right;
m->right=tree;
return m;
}