[英]Inserting AVL tree in C
我正在實現一個AVL樹及其諸如旋轉的操作。
最后,當我嘗試插入數組時,結果似乎
不同。 有人告訴我出了什么問題! 謝謝 !
#include <stdio.h>
#include <stdlib.h>
#define LH +1
#define RH -1
#define EQ 0
typedef int BOOL;
typedef struct node
{
int bf;
struct node *left;
struct node *right;
int val;
}treeNode;
void L_Rotate(treeNode **T)
{
treeNode *p = (*T)->right;
(*T)->right = p->left;
p->left=*T;
*T=p;
}
void R_Rotate(treeNode **T)
{
treeNode *p=(*T)->left;
(*T)->left=p->right;
p->right=*T;
*T=p;
}
void Left_Balance(treeNode **T)
{
treeNode *p=(*T)->left;
treeNode *q;
switch(p->bf)
{
case LH:
p->bf=(*T)->bf=EQ;
R_Rotate(T);
break;
case RH:
q = p->right;
switch(q->bf)
{
case LH:
(*T)->bf=RH;
p->bf=EQ;
break;
case EQ:
(*T)->bf=q->bf=EQ;
break;
case RH:
p->bf=LH;
(*T)=EQ;
break;
}
q->bf=EQ;
L_Rotate(&p);
R_Rotate(T);
}
}
void Right_Balance(treeNode **T)
{
treeNode *p=(*T)->right;
treeNode *q;
switch(p->bf)
{
case RH:
(*T)->bf=p->bf=EQ;
L_Rotate(T);
break;
case LH:
q=p->left;
switch(q->bf)
{
case LH:
(*T)->bf=EQ;
p->bf=RH;
break;
case RH:
(*T)->bf=LH;
p->bf=EQ;
break;
}
q->bf=EQ;
R_Rotate(&p);
L_Rotate(T);
}
}
int insertAVL (treeNode **T,int key, BOOL *taller)
{
if(!*T)
{
*T=malloc(sizeof(treeNode));
if(!*T) return 0;
(*T)->left=(*T)->right=NULL;
(*T)->bf=EQ;
*taller = 1;
(*T)->val=key;
}
else
{
if(key==(*T)->val)
{
*taller= 0;
return 0;
}
else if(key<(*T)->val)
{
if(!insertAVL(&(*T)->left,key,taller)) return 0;
if(*taller)
{
switch((*T)->bf)
{
case LH:
Left_Balance(T);
*taller=0;
break;
case RH:
(*T)->bf=EQ;
*taller =0;
break;
case EQ:
(*T)->bf=LH;
*taller =1;
break;
}
}
}
else
{
if(!insertAVL(&(*T)->right,key,taller)) return 0;
if(*taller)
{
switch((*T)->bf)
{
case LH:
(*T)->bf=EQ;
*taller=0;
break;
case EQ:
(*T)->bf=RH;
*taller=1;
break;
case RH:
Right_Balance(T);
*taller =0;
break;
}
}
}
}
return 1;
}
void preOrder(treeNode *T)
{
if(!T)
{
return;
}
printf("%d\n",T->val);
preOrder(T->left);
preOrder(T->right);
}
int main() {
int i;
int a[10]={3,2,1,4,5,6,7,10,9,8};
treeNode *T=NULL;
BOOL taller;
for(i=0;i<10;i++)
{
insertAVL(&T,a[i],&taller);
preOrder(T);
printf("-------\n");
}
return 0;
}
每次插入樹后我都遍歷了樹,結果是
直到我將9插入樹中。
修改樹(或子樹)時,您將指針傳遞給head指針,以便更改反映在原始鏈接中,該鏈接是全局頭或節點的左/右鏈接之一。 我認為這是一個好習慣。
平衡樹時,您也可以這樣做,但有一個陷阱:
treeNode *p = (*T)->left;
// ... some stuff ...
L_Rotate(&p);
R_Rotate(T);
在這里, p
是(*T)->left
的本地副本。 您最終將修改一個局部變量(該變量將立即超出范圍),而不是父節點中的實際鏈接。 該節點被“吃掉”。
您也可以將p
為treeNode **
,或者,如果不更改指針本身,則將旋轉代碼更改為:
L_Rotate(&(*T)->left);
R_Rotate(T);
對於其他旋轉也是如此。
我還注意到您的左右平衡功能不對稱,並且右平衡代碼缺少EQ情況。 我做了一些嘗試將其添加並重寫Right_Balance
以使其與Right_Balance
對稱, Left_Balance
任何問題。 問題不僅僅在這里。
如果我對管理AVL沒錯,則必須考慮每個像元的高度 ,以決定在插入新值后如何進行平衡。
在您的情況下,沒有高度,但是bf能夠獲得3個值LH / RH / EQ,因此bf等於高度范圍1到3之間的高度。但是在插入10后,具有4值的單元格實際上具有高度4,您無法管理,對我來說,這就是為什么您不能在10之后正確插入9的原因。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.