构造AVL树

AVL数是平衡的二叉排序树的一种,AVL树中任一节点的左右子树的高度之差的绝对值不超过1。

什么是平衡的二叉树呢?树中任一节点的左右子树的高度大致相同,若任一结点的左右子树的高度均相同(如满二叉树),则二叉树是完全平衡的。

二叉排序树(Binary Sort Tree)的性质:
(1)若它的左子树非空,则左子树上的所有结点的值均小于根结点的值。
(2)若它的右子树非空,则右子树上的所有结点的值均大于根结点的值。
(3)左右子树本身又各是一棵二叉排序树。

下面编写一个程序,它能读入n(n<=20)个两两不等的整数,最后一个是-9999,作为结束标志,构造一棵包含这n 个整数的AVL树,然后前 中 后序遍历树,算出树的高度。

这个程序的关键就是构造AVL 树,我们可以从空的AVL树开始,读入一个数就插入,再检测插入后是否符合AVL树性质,如不符合就进行调整。
还有一种方法,先对输入的数排序,再把中点的数插入AVL树中,对中点左右两边的的序列采用同样的插入方法,直到空为止。
第二种方法比较简单,我们的程序就采用此方法。


#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
#define MAX 20
int acturalNum = 0; //实际输入的节点数

struct Node{
int key;
struct Node *lchild, *rchild;
};
typedef struct Node TNode;
typedef struct Node * TreeNode;
TreeNode root = NULL;

/**
* 接收节点,以"-9999"结束
*/

void inputNode(int node[]){
int i;
int temp = -9999;
int index = 0;

for(i=0; i<MAX; i++)
node<i> = -9999;

while(1){
scanf("%d", &temp);
if(temp == -9999)
break;
acturalNum++;
node[index++] = temp;
}
}

/**
* 对接收的节点按从小到大排序
*/

void sortNode(int node[]){
int i,j,temp;
for(i=0; i<acturalNum; i++)
for(j=0; j<acturalNum-1; j++)
if(node[j] > node[j+1]){
temp = node[j];
node[j] = node[j+1];
node[j+1] = temp;
}
}

/**
* 构造AVL树
*/

void createAVL(TreeNode tNode, int node[], int start, int end){
TreeNode lRoot = NULL;
TreeNode rRoot = NULL;
int lStart, lEnd, rStart, rEnd, key, lKey, rKey;

key = (start + end)/2;
if(key < start || key > end)
return;
tNode->key = node[key];

lStart = start;
lEnd = key -1;

if(lStart >= start && lStart <= lEnd
&& lEnd >= lStart && lEnd <= end){

lKey = (lStart + lEnd)/2;
lRoot = (TreeNode)malloc(sizeof(struct Node));
lRoot->key = node[lKey];
lRoot->lchild = NULL;
lRoot->rchild = NULL;
tNode->lchild = lRoot;
}

rStart = key + 1;
rEnd = end;

if(rStart >= start && rStart <= rEnd
&& rEnd >= rStart && rEnd <= end){

rKey = (rStart + rEnd)/2;
rRoot = (TreeNode)malloc(sizeof(struct Node));
rRoot->key = node[rKey];
rRoot->lchild = NULL;
rRoot->rchild = NULL;
tNode->rchild = rRoot;
}

createAVL(lRoot, node, lStart, lEnd);
createAVL(rRoot, node, rStart, rEnd);

}

void inorder(TreeNode tNode){
if(tNode){
inorder(tNode->lchild);
printf("%5d", tNode->key);
inorder(tNode->rchild);
}
}

void preorder(TreeNode tNode){
if(tNode){
printf("%5d", tNode->key);
preorder(tNode->lchild);
preorder(tNode->rchild);
}
}

void postorder(TreeNode tNode){
if(tNode){
postorder(tNode->lchild);
postorder(tNode->rchild);
printf("%5d", tNode->key);
}
}

/**
* 计算树高度
*/

int height(TreeNode tNode){
int lHeight = 0;
int rHeight = 0;
TreeNode temp = tNode;

while(1){
lHeight++;
if(temp->lchild == NULL)
break;
temp = temp->lchild;
}

temp = tNode;
while(1){
rHeight++;
if(temp->rchild == NULL)
break;
temp = temp->rchild;
}

return lHeight > rHeight? lHeight:rHeight;
}

void main(){
TreeNode tree = NULL;
int node[MAX];
inputNode(node);
sortNode(node);

root = (TreeNode)malloc(sizeof(struct Node));
root->key = node[(acturalNum -1)/2];
root->lchild = NULL;
root->rchild = NULL;

createAVL(root, node, 0, acturalNum -1);

printf("pre order : ");
preorder(root);

printf("\nin order   : ");
inorder(root);

printf("\npost order: ");
postorder(root);

printf("\nHeight: %d \n", height(root));
}

posted on 2010-05-19 20:37  画一个圆圈  阅读(374)  评论(0编辑  收藏  举报

导航