//Binary Tree Search 삽입, 삭제, 균형잡기

#include<stdio.h>
#include<stdlib.h>
#define MAX 100

typedef struct _node
{
    char data;
    struct _node* left;
    struct _node* right;
}node;

 int index; 
char array[MAX];

 void print(node*);
void print2(node*);
node* insert(node**, char);
node* del(node**, char);
void bti_balance(node**);
node* balance(int);
void bti_deleteall(node**);
void bti_sort(node**);

 void main()
{
    node* root = NULL;

    insert(&root, 'F');
    insert(&root, 'B');
    insert(&root, 'O');
    insert(&root, 'L');
    insert(&root, 'A');
    insert(&root, 'D');
    insert(&root, 'C');
    insert(&root, 'M');
    insert(&root, 'G');
    insert(&root, 'H');
    insert(&root, 'N');
    insert(&root, 'K');

    print2(root);   printf("\n");   print(root);    printf("\n\n");

    del(&root, 'F');    print2(root);   printf("\n");   print(root);    printf("\n\n");

    bti_balance(&root);
    print2(root);   printf("\n");   print(root);    printf("\n");
}


void bti_balance(node** base)
{
    int i;
    index = 0;
    bti_sort(&(*base));
    i = index;
    bti_deleteall(&(*base));
    index = 0;
    *base = balance(i);
}

 // 이진 트리 균형잡는 함수
node* balance(int n)
{
    int n_left, n_right;
    node* temp;
    if(n > 0)
    {
        n_left = (n-1)/2;
        n_right = n - n_left - 1;
        temp = (node*)malloc(sizeof(node));
        temp->left = balance(n_left);
        temp->data = array[index++];
        temp->right = balance(n_right);
        return temp;
    }
    else
        return NULL;
}

 // 이진 트리 모든 노드 삭제 함수
void bti_deleteall(node** p)
{
    if(*p != NULL)
    {
        bti_deleteall(&(*p)->left);
        bti_deleteall(&(*p)->right);
        free(*p);
    }
}

 // 이진 트리를 순회 하면서 값을 배열에 저장하는 함수
void bti_sort(node** p)
{
    if(*p != NULL)
    {
        bti_sort(&(*p)->left);
        array[index++] = (*p)->data;
        bti_sort(&(*p)->right);
    }
}

node* del(node** base, char key)
{
    node *temp, *son, *nexth, *parent;
    int flag = 0;
    temp = *base;
    while(temp->data != key && temp != NULL)
    {
        flag = 1;
        parent = temp;
        if(temp->data > key)
            temp = temp->left;
        else
            temp = temp->right;
    }
    if(temp == NULL)
        return NULL;
    if(temp->left == NULL && temp->right == NULL)  // 노드의 자식이 없는 경우
        son = NULL;
    else if(temp->left != NULL && temp->right != NULL)  // 노드의 자식이 둘인 경우
    {
        nexth = temp->right;
        if(nexth->left != NULL)  // 노드의 오른쪽 자식의 왼쪽 자식이 있는 경우
        {
            while(nexth->left->left != NULL)
                nexth = nexth->left;
            son = nexth->left;
            nexth->left = son->right;
            son->left = temp->left;
            son->right = temp->right;
        }
        else  // 노드의 오른쪽 자식의 왼쪽 자식이 없는 경우
        {
            son = nexth;
            son->left = temp->left;
        }
    }
    else  // 노드의 자식이 하나인 경우
    {
        if(temp->left != NULL)
            son = temp->left;
        else
            son = temp->right;
    }

    if(flag)
    {
        if(parent->data > key)
            parent->left = son;
        else
            parent->right = son;
    }
    else
        *base = son;
    free(temp);
    return son;
}

 

void print(node* base)
{
    node* temp = base;
    if(temp != NULL)
    {
        print(temp->left);
        printf("%3c",temp->data);
        print(temp->right);
    }
}

 void print2(node* base)
{
    node* temp = base;
    if(temp != NULL)
    {
        printf("%3c",temp->data);
        print2(temp->left);
        print2(temp->right);
    }
}

 node* insert(node** base, char key)
{
    if((*base) == NULL)
    {
        (*base) = (node*)malloc(sizeof(node));
        (*base)->data = key;
        (*base)->left = NULL;
        (*base)->right = NULL;
    }
    else if((*base)->data > key)
        (*base)->left = insert(&(*base)->left, key);
    else
        (*base)->right = insert(&(*base)->right, key);
    return *base;
}

+ Recent posts