ㅇTL

AVL tree 본문

2-1/자료구조 (c)

AVL tree

정노르레기 2022. 5. 30. 18:17

정의 : 모든 노드에 대해서 노드의 왼쪽 서브트리와 오른쪽 서브트리의 높이차가 1이하는 BST (이진탐색트리)

리프노드의 height=0

균형도 값 = 좌측서브트리의 높이-우측서브트리의 높이.

이게 1보다 커지면 회전을 한다

*아무것도 없는것 : -1로 가정함 ! (NULL=-1)

이 값이 양수 -> 왼쪽 치우침 / 음수 -> 오른쪽 치우침

 

높이 결정법

MAX(좌 서브트리높이, 우서브트리높이) + 1 

(둘중 더 큰 값 + 1 이 높이가 됩니당)

 

LL: 왼쪽으로 치우쳐있으므로 오른쪽으로 회전함

RR: 오른쪽으로 치우쳐 있으므로 왼쪽으로 회전

(이건 반대로 회전)

(얘넨 그대로 회전)

LR : 왼쪽으로 치우쳤는데 왼쪽노드의 오른쪽서브트리가 더 무거울때 함

(왼쪽무겁-의 오른쪽무겁 이라서 LR) < 모양

-> 왼쪽서브노드에 좌회전하고 전체에 우회전함

RL : 오른쪽으로치우쳤는데 오른쪽노드의 왼쪽서브트리가 더 무거울때 (1이라도) > 모양

 

이지하네욤~^^ 아래꺼 예제 마니 해보긩

 

두개가 아래로 더튀어나와잇으면 회전!!!

 

회전할땐 양끝연결

 

 

코드 실습

easy 하네영

 

1. rotate LL (우회전)

- 부모의 왼쪽을 왼쪽자식의 오른쪽노드로 설정

- 왼쪽자식의 오른쪽노드를 부모로 설정

-높이 변경; 부모, 왼쪽자식 각각 두자식중 큰 높이 + 1 를 높이로 설정해줌

-> 왼쪽자식 (child 리턴)

AvlNode* rotateLL(AvlNode* parent){
    AvlNode* child=parent->left;//할당
    
    parent->left=child->right;
    child->right=parent; 
    
    //child의 자식에는 parent가 있으므로 parent의 높이 먼저 설정해야함!!
    // 위 아래 둘다 parent 먼저 !!
    parent->Height=Max(height(parent->left), height(parent->right))+1; //+1까먹지 말깅
    child->height=//얘도 마찬가지
   
    //height 함수는 null일 경우 -1 리턴, 아닐경우 걍 height 리턴해주는 함수 ! null일때 때문에 만들어둠
}

2. rotate RR

-오른쪽 자식 노드 할당

-부모먼저!! 부모의 오른쪽=자식의 왼쪽자식

-자식의 왼쪽=부모

-이제 h변경!! 걍 부모먼저~~ 끗 (이때 +1 잊지말기~~)

AvlNode* child=parent->right;

parent->right=child->left;
child->left=parent;

parent->Height=Max(height(parent->left), height(parent->right))+1;
child->Height=Max(parent->Height, height(child->right))+1;

 

3. rotate LR

- left 자식이 오른쪽으로 기울어져있으므로 RR rotate 시킴

그리고 해당 노드 LL rotate

-> LR이므로 left=RR로테이션, 그리고 LL

(RR->LL)

AvlNode* child=parent->left;
parent->left=rotateRR(child); //RR rotate한걸로 새로 끼워넣기 ^^
return rotateLL(parent);

4. rotate RL

(LL->RR)

AvlNode* child=parent->right;
parent->right=rotateLL(child);
return rotateRR(parent);

5. insert

- root=null이면 루트에 추가

 

- 데이터 값이 루트보다 작으면

 재귀로 left로 계속 간다 (root->left=avlAdd(root->left,data); )

 추가하고 나서는 왼.오 차이가 2-> 두개로 나뉨 .

 데이터가 루트의 왼쪽애보다 작으면 LL(왼쪽에추가된거니까), 아니면 LR (오른쪽에추가된거니까)

 

 

- 데이터 값이 루트보다 크면

  위에의 반대로

 

- root의 height 설정. 왼,오 height중 max인거 후 +1

- return root

 

AvlNode* avlAdd(AvlNode* root, int data){
    if(root==NULL){
        root=(AvlNode*)malloc(sizeof(AvlNode));
        if(root==NULL){
            exit(1);
        }
        root->data=data;
        root->Height=0;
        root->left=root->right=NULL;
    }
    else if(data<root->data){
        root->left = avlAdd(root->left, data);
        //
        if(height(root->left)-height(root->right)==2){
            if(data<root->left->data)
                root=rotateLL(root);
            else
                root=rotateLR(root);
        }
    }
    else if(data>root->data){
        root->right=avlAdd(root->right, data);
        //
        if(height(root->right)-height(root->left)==2){
            if(data>root->right->data)
                root=rotateRR(root);
            else
                root=rotateRL(root);
        }
    }
    else{
        printf("중복 키 삽입 오류\n");
        exit(1);
    }
    root->Height=Max(height(root->left), height(root->right))+1;
    return root;
}

'2-1 > 자료구조 (c)' 카테고리의 다른 글

Sorting  (0) 2022.06.02
Hash  (0) 2022.05.31
Heap  (0) 2022.05.30
Stack, queue  (0) 2022.04.17
Binary tree  (0) 2022.04.13