索引--优化数据结构--平衡二叉树(avl)

来源:互联网 发布:sql 更改字段属性 编辑:程序博客网 时间:2024/06/01 08:18

天下文章一大抄,最近在做第二版的搜索引擎,比起第一版总要有很大的改进才行。

首先想到的是要对数据结构进行优化,就要把原来“倒排索引--二叉树”http://blog.csdn.net/txgc0/article/details/8697380

这边文章中提到的二叉树进行优化,众所周知,单纯的简单二叉树的坏处就怕退化,退化成一条链表后,这查找速度是相当难以让人接受的。

平衡二叉树的好处就是可以使时间复杂度保持在logN,不至于最坏的情况出现。

当然,越是好东西,越麻烦。

平衡二叉树就最复杂的情况就是树的旋转。这种旋转的过程可以查阅网上的很多文章,说的也比较详细,不过我建议,还是最好自己画画,看看是怎么样一个转换过程。

我算是借鉴一下某位大神的文章得出以下代码:

avl.c

#include "avl.h"#include "utl.h"static int Max(int a, int b);static int Height(struct AVLTree* pNode);static struct AVLTree* SingleRotateWithLeft(struct AVLTree* pNode);static struct AVLTree* SingleRotateWithRight(struct AVLTree* pNode);static struct AVLTree* DoubleRotateWithLeft(struct AVLTree* pNode);static struct AVLTree* DoubleRotateWithRight(struct AVLTree* pNode);struct AVLTree* insert_tree(unsigned int nData, struct AVLTree* pNode){    if (NULL == pNode)    {        pNode = (struct AVLTree*)xmalloc(sizeof(struct AVLTree));        pNode->nData = nData;        pNode->nHeight = 0;        pNode->pLeft = pNode->pRight = NULL;    }    else if (nData < pNode->nData)        {        pNode->pLeft = insert_tree(nData, pNode->pLeft);        if (Height(pNode->pLeft) - Height(pNode->pRight) == 2)           {            if (nData < pNode->pLeft->nData)            {                pNode = SingleRotateWithLeft(pNode);            }            else            {                pNode = DoubleRotateWithLeft(pNode);            }        }    }    else if (nData > pNode->nData)       {        pNode->pRight = insert_tree(nData, pNode->pRight);        if (Height(pNode->pRight) - Height(pNode->pLeft) == 2)           {            if (nData > pNode->pRight->nData)            {                pNode = SingleRotateWithRight(pNode);            }            else            {                pNode = DoubleRotateWithRight(pNode);            }        }    }    pNode->nHeight = Max(Height(pNode->pLeft), Height(pNode->pRight)) + 1;    return pNode;}void delete_tree(struct AVLTree** ppRoot){    if (NULL == ppRoot || NULL == *ppRoot)        return;    delete_tree(&((*ppRoot)->pLeft));    delete_tree(&((*ppRoot)->pRight));    xfree(*ppRoot);    *ppRoot = NULL;}void print_tree(struct AVLTree* pRoot){static int n = 0;    if (NULL == pRoot)        return;        print_tree(pRoot->pLeft);    printf("[%d]nData = %u\n", ++n, pRoot->nData);    print_tree(pRoot->pRight);}int find_tree(unsigned int data, struct AVLTree* pRoot){    static int k=1;       if (NULL == pRoot)    {        printf("not find %d times\n", k);        return 0;    }    if(data == pRoot->nData)    {        printf("find:%d times\n", k);        return 1;    }    else if(data < pRoot->nData)    {        ++k;        return find_tree(data, pRoot->pLeft);    }    else if(data > pRoot->nData)    {        ++k;        return find_tree(data, pRoot->pRight);    }return 0;}static int Max(int a, int b){    return (a > b ? a : b);}static int Height(struct AVLTree* pNode){    if (NULL == pNode)        return -1;    return pNode->nHeight;}/********************************************************************      pNode pNode->pLeft      / \  pNode->pLeft ==> pNode      \     /  pNode->pLeft->pRight pNode->pLeft->pRight *********************************************************************/static struct AVLTree* SingleRotateWithLeft(struct AVLTree* pNode){    struct AVLTree* pNode1;    pNode1 = pNode->pLeft;    pNode->pLeft = pNode1->pRight;    pNode1->pRight = pNode;    pNode->nHeight = Max(Height(pNode->pLeft), Height(pNode->pRight)) + 1;    pNode1->nHeight = Max(Height(pNode1->pLeft), pNode->nHeight) + 1;    return pNode1;}/********************************************************************  pNode pNode->pRight  \ /  pNode->pRight ==> pNode  / \  pNode->pRight->pLeft pNode->pRight->pLeft *********************************************************************/static struct AVLTree* SingleRotateWithRight(struct AVLTree* pNode){    struct AVLTree* pNode1;    pNode1 = pNode->pRight;    pNode->pRight = pNode1->pLeft;    pNode1->pLeft = pNode;    pNode->nHeight = Max(Height(pNode->pLeft), Height(pNode->pRight)) + 1;    pNode1->nHeight = Max(Height(pNode1->pRight), pNode->nHeight) + 1;    return pNode1;}static struct AVLTree* DoubleRotateWithLeft(struct AVLTree* pNode){    pNode->pLeft = SingleRotateWithRight(pNode->pLeft);    return SingleRotateWithLeft(pNode);}static struct AVLTree* DoubleRotateWithRight(struct AVLTree* pNode){    pNode->pRight = SingleRotateWithLeft(pNode->pRight);    return SingleRotateWithRight(pNode);}


avl.h

#ifndef __AVL_H__#define __AVL_H__struct AVLTree{    unsigned int nData;        struct AVLTree* pLeft;       struct AVLTree* pRight;       int nHeight;   };struct AVLTree* insert_tree(unsigned int nData, struct AVLTree* pNode);extern int find_tree(unsigned int data, struct AVLTree* pRoot);void delete_tree(struct AVLTree** ppRoot);extern void print_tree(struct AVLTree* pRoot);#endif


main.c

#include <time.h>#include "avl.h"#include "utl.h"int main(){    int i,j;    struct AVLTree* pRoot = NULL;    srand((unsigned int)time(NULL));        for (i = 0; i < 10; ++i)    {            j = rand();            printf("%d\n", j);pRoot = insert_tree(j, pRoot);    }//    PrintTree(pRoot); //   DeleteTree(&pRoot);    return 0;}


utl.h

#ifndef __UTL_H__#define __UTL_H__#include <stdio.h>#include <stdlib.h>inline void *xmalloc(int size){    void *p;    p = (void *)malloc(size);    if(p == NULL)    {        printf("alloc error\n");        exit(1);    }    return p;}#define xfree(p) free(p)#endif


我得尊重作者的劳动成果,不知道是不是这位大神手写的,但是我是从这里看到的,所以我要注明来处的链接:

http://blog.csdn.net/w397090770/article/details/8119616

说实话,他写的真好。。。。增加一下人品。

原创粉丝点击