1. 程式人生 > >資料結構實驗之查詢二:平衡二叉樹 (SDUT 3374)

資料結構實驗之查詢二:平衡二叉樹 (SDUT 3374)

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

struct node
{
    int data;
    int h;
    struct node *lc,*rc;  //平衡二叉樹 需要一個 h 來記錄平衡因子
};

int max(int x ,int y)  
{
    if(x > y) return x;
    else return y;
}

int fin(struct node *root)   // 返回這個結點的平衡因子,也就是左右子樹的差值
{
    if(root == NULL) return -1;
    else return root -> h;
}

struct node *LL(struct node *root)  // 如果是左左型,也就是呈現 根 - 左子樹 p - 左子樹2 , 我們要把 根 變成 p 的右子樹 
{
    struct node *p = root -> lc;
    root -> lc = p -> rc;
    p -> rc = root;
    p -> h = max(fin(p->lc),fin(p->rc)) + 1;  // 更新這兩個點的平衡因子
    root -> h = max(fin(root->lc),fin(root->rc)) + 1;
    return p;  //別忘記返回 p
}

struct node *RR(struct node *root)  // 同上相反
{
    struct node *p = root -> rc;
    root -> rc = p -> lc;
    p -> lc = root;
    p -> h = max(fin(p->lc),fin(p->rc));
    root -> h = max(fin(root->lc),fin(root->rc)) + 1;
    return p;
}

struct node *LR(struct node *root)  //LR型, 形如 根 - 左子樹 - 右子樹 
{
    root -> lc = RR(root -> lc);
    return LL(root);
}

struct node  *RL(struct node *root)
{
    root -> rc = LL(root -> rc);
    return RR(root);
}

struct node *creat(struct node *root, int x)  // 建樹的過程
{
    if(root == NULL)  //如何到底層或者到可以放這個數的地方
    {
        root = (struct node *)malloc(sizeof(struct node));
        root -> data = x;
        root -> lc = root -> rc = NULL; // 左右孩子、h 初始化
        root -> h = 0;
    }
    else if(root -> data > x)  // 如果小的話,找左子樹,
    {
        root -> lc = creat(root -> lc, x);
        if(fin(root->lc) - fin(root->rc) > 1) // 如果找完之後,放進去之後,判斷時候不平衡了,如果不平衡,判斷是什麼樣子的型別,再旋轉
        {
            if(root -> lc -> data > x) root = LL(root);  // LL型,因為如果 root -> lc -> data > x,那麼 x 是放在了這個的左子樹
            else root = LR(root);  //相反,這樣子會放在右子樹
        }
    }
    else if(root -> data < x)
    {
        root -> rc = creat(root -> rc, x);
        if(fin(root->rc) - fin(root->lc) >1)
        {
            if(root -> rc -> data < x) root = RR(root);
            else root = RL(root);
        }
    }
    root -> h = max(fin(root->lc),fin(root->rc)) + 1;  // 沒插入一次新值,更新 root 的平衡因子
    return root;
}
int main()
{
    int n,m;
    scanf("%d",&n);
    struct node *root = NULL;
    for(int i = 0; i < n; i ++)
    {
        scanf("%d",&m);
        root = creat(root,m);
    }
    printf("%d\n",root->data);
    return 0;
}