天下文章一大抄,最近在做第二版的搜索引擎,比起第一版总要有很大的改进才行。
首先想到的是要对数据结构进行优化,就要把原来“倒排索引--二叉树 ”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
说实话,他写的真好。。。。增加一下人品。
在构建第二版搜索引擎时,为了提高数据结构的效率,作者决定对原始的二叉树进行优化,采用平衡二叉树——AVL树。AVL树能确保查找操作的时间复杂度保持在O(logN),避免了二叉树退化为链表后的性能问题。文章提到了AVL树旋转的重要性,并鼓励读者亲自绘制旋转过程以理解其工作原理。作者分享了部分代码,并引用了CSDN上的一篇文章作为参考来源。
&spm=1001.2101.3001.5002&articleId=8876888&d=1&t=3&u=2d032a59f790415b8721d6f7ae50d6b3)
6335

被折叠的 条评论
为什么被折叠?



