【平衡二叉樹】數據結構實驗之查找二:平衡二叉樹

平衡二叉樹

剛開始接觸平衡二叉樹,沒有什麼太多要分析的。博客裏有很多大佬們都寫的很好。平衡二叉樹就是每個節點的子樹的高度差不超過1的二叉樹。可以快速搜索數值的一種算法,最糟的情況就是一直找到底,但也是log(n)的。還是快很多。

#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#define max(a , b) (a > b ? (a) : (b))
struct tree
{
    int data, d;
    struct tree *ltree, *rtree;
};

int deep(struct tree *root)//計算深度
{
    if(!root)
    {
        return 0;
    }
    else
        return root->d;
}

struct tree *LL(struct tree *root)//LL型,就是右旋。插入的是左樹的左兒子。
{
    struct tree *p = root->ltree;
    root->ltree = p->rtree;
    p->rtree = root;
    root->d = max(deep(root->ltree), deep(root->rtree)) + 1;//記住每次旋轉之後根位置變化了,要從新計算深度。
    return p;
}

struct tree *RR(struct tree *root)//RR型,就是左旋。插入的是右樹的右兒子。
{
    struct tree *p = root->rtree;
    root->rtree = p->ltree;
    p->ltree = root;
    root->d = max(deep(root->ltree), deep(root->rtree)) + 1;//記住每次旋轉之後根位置變化了,要從新計算深度。
    return p;
}

struct tree *LR(struct tree *root)//LR型,要先左旋再右旋,插入的是左樹的右兒子。
{
    root->ltree = RR(root->ltree);
    root = LL(root);
    return root;
}

struct tree *RL(struct tree *root)//RL型,要先右旋再左旋,插入的事右樹的左兒子。
{
    root->rtree = LL(root->rtree);
    root = RR(root);
    return root;
}

struct tree *creat(struct tree *root, int m)
{
    if(!root)
    {
        root = (struct tree *)malloc(sizeof(struct tree));
        root->data = m;
        root->d = 1;//每次生成把深度記爲1,當然0也可以(就是要在計算深度的地方要記得改爲 return -1;)
        root->ltree = root->rtree = NULL;
        return root;
    }
    else
    {
        if(root->data > m)//插入二叉樹的左樹
        {
            root->ltree = creat(root->ltree, m);
            if(deep(root->ltree) - deep(root->rtree) > 1)
            {
                if(root->ltree->data > m)//左樹的左兒子
                {
                    root = LL(root);
                }
                else//左樹的右兒子
                {
                    root = LR(root);
                }
            }
        }
        else//插入二叉樹的右樹
        {
            root->rtree = creat(root->rtree, m);
            if(deep(root->rtree) - deep(root->ltree) > 1)
            {
                if(root->rtree->data > m)//右樹的左兒子
                {
                    root = RL(root);
                }
                else//右樹的右兒子
                {
                    root = RR(root);
                }
            }
        }
    }
    root->d = max(deep(root->ltree), deep(root->rtree)) + 1;//計算根的深度。
    return root;
}

int main()
{
    int n, m;
    while(~scanf("%d", &n))
    {
        struct tree *root = NULL;//指針暫時不用的時候要記得初始化爲NULL。要不會很恐怖不信你試試。
        while(n--)
        {
            scanf("%d", &m);
            root = creat(root, m);
        }
        printf("%d\n", root->data);
    }
    return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章