数据结构把我搞傻了
决定开始记录自己的啃题历程
6-1 AVL Insertion (25分)
You are supposed to implement the Insert function, which inserts an integer Key into an AVL tree T. The resulting tree must be returned.
您应该实现Insert函数,该函数将一个整数Key插入AVL树T。必须返回结果树。
Format of function:
AVLTree Insert ( AVLTree T, int Key );
where AVLTree is defined as the following:
定义AVLTree结构如下
typedef struct AVLNode *PtrToAVLNode;
struct AVLNode{
int Key;
PtrToAVLNode Left;
PtrToAVLNode Right;
int Height;
};
typedef PtrToAVLNode AVLTree;
Sample program of judge:
#include <stdio.h>
#include <stdlib.h>
typedef struct AVLNode *PtrToAVLNode;
struct AVLNode{
int Key;
PtrToAVLNode Left;
PtrToAVLNode Right;
int Height;
};
typedef PtrToAVLNode AVLTree;
AVLTree Insert ( AVLTree T, int Key );
void PostOrderPrint( AVLTree T ); /* details omitted */
void InOrderPrint( AVLTree T ); /* details omitted */
int main()
{
int N, Key, i;
AVLTree T = NULL;
scanf("%d", &N);
for ( i=0; i<N; i++ ) {
scanf("%d", &Key);
T = Insert( T, Key );
}
PostOrderPrint( T );
InOrderPrint( T );
return 0;
}
/* Your function will be put here */
Sample Input:
7
88 70 61 96 120 90 65
Sample Output:
Post-order: 61 70 65 90 120 96 88
In-order: 61 65 70 88 90 96 120
想要做对这个题首先要知道AVL树——平衡二叉树是什么,其具有以下性质:
1、是一棵空树或者左右两子树高度差的绝对值不超过1。
2、左右两子树都是平衡二叉树。
本题要求我们实现将一个整数Key插入AVL树T。必须返回结果树(也就是返回根节点即可,题目会自动输出)。
伪代码:
①读入要插入的Key值,要插入到哪棵树T;
②判断T树是否为空
如果为空
直接返回一个新结点,
否则
如果比根结点的值小,向左子树插入;
如果比根节点的值大,向右子树插入;
如果就是根节点的值直接返回根节点。
③插入后更新高度。
④插入后的调整,计算平衡因子,如果左子树高并且Key值小于左子树的根节点Key值,右旋;
如果右子树高,Key值大于右子树根节点Key值,左旋;
左子树高,Key值大于左子树Key值,RL;
右子树高,Key值小于右子树Key值,LR。
⑤返回根节点。
需要实现的几个函数
//比较大小
int max(int a, int b);
//获取高度
int height(struct AVLNode *T);
//构造新结点
srtuct AVLNode *NewNode(int key);
//右旋
struct AVLNode *R(struct AVLNode *y);
//左旋
struct AVLNode *L(struct AVLNode *y);
//返回左右子树高度差判断是否平衡
int Balance(struct AVLNode *T);
//插入
AVLTree Insert ( AVLTree T, int Key );
来逐个实现他们
//比较大小
int max(int a, int b){
return (a > b) ? a : b;
}
//获取高度
int height(struct AVLNode *T){
if(T == NULL) retuen 0;//如果树为空 直接返回0
return T -> Height;//不为空返回高度
}
//构造新结点
srtuct AVLNode *NewNode(int key){
//申请一个新结点空间
struct AVLNode *node = (struct AVLNode *)malloc(struct AVLNode);
//结点赋值 左右子树为空 高度为1
node -> Key = Key;
node -> Left = NULL;
node -> Right = NULL;
node -> Height = 1;
//返回结点
return node;
}
//右旋
struct AVLNode *R(struct AVLNode *y){
//第一幅图
struct AVLNode *x = y -> Left;
struct AVLNode *t1 = x -> Right;
//第二幅图
x -> Righrt = y;
y -> Left = t1;
//更新高度
x->Height = max(height(x->Left), height(x->Right))+1;
y->Height = max(height(y->Left), height(y->Right))+1;
//返回根节点
return x;
}
//左旋
struct AVLNode *L(struct AVLNode *y){
//第一幅图
struct AVLNode *x = y -> Right;
struct AVLNode *t2 = x -> Left;
//第二幅图
x -> Left = y;
y -> Right = t2;
//更新高度
x->Height = max(height(x->Left), height(x->Right))+1;
y->Height = max(height(y->Left), height(y->Right))+1;
//返回头结点
return x;
}
//返回左右子树高度差判断是否平衡
int Balance(struct AVLNode *T){
if(T == NULL) return 0;
return height(T -> Left) - height(T -> Right);//返回高度差
}
//插入
AVLTree Insert ( AVLTree T, int Key ){
if(T = NULL) return NewNode(Key);
if(Key < T -> Key)
T -> Left = Insert(T -> Left, Key);
else if(Key > T -> Key)
T -> Right = Insert(T -> Right, Key);
else return T;
T -> Height = 1 + max(height(T->Left), height(T->Right));
int balance = Balance(T);
if (balance > 1 && Key < T->Left->Key)
return R(T);
if (balance < -1 && Key > T->Right->Key)
return L(T);
if (balance > 1 && Key > T->Left->Key) {
T->Left = L(T->Left);
return R(T);
}
if (balance < -1 && Key < T->Right->Key) {
T->Right = R(T->Right);
return L(T);
}
return T;
}
完结撒花
(其实我还没有彻底搞明白,但大题思想和大致代码怎么写理解的差不多了。