// AVL.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
using namespace std;
//最近需要面试,写以下二查平衡树的插入,删除代码。加深印象,其中的难点是旋转问题。
//有不正确的地方,恳请批评指正!
typedef struct node //结点的数据结构
{
int value;
node* left;
node* right;
int height;
node(int x):value(x),left(NULL),right(NULL),height(1){}
}node;
int height(node* p) //返回结点的高度
{
if(p == NULL)
return 0;
else
return p->height;
}
//左左情况下的调整
void SingleRoateLeft(node* &k2)
{
node* k1=k2->left;
k2->left = k1->right;
k1->right = k2;
k2->height = max(height(k2->left),height(k2->right))+1;
k1->height = max(height(k1->left),height(k1->right))+1;
k2 = k1;
}
//右右情况下的调整
void SingleRoateRight(node* &k2)
{
node* k1 = k2->right;
k2->right = k1->left;
k1->left = k2;
k2->height = max(height(k2->left),height(k2->right))+1;
k1->height = max(height(k1->left),height(k1->right))+1;
k2 = k1;
}
//左右情况下的调整
void DoubleRoateLR(node* &k3)
{
SingleRoateRight(k3->left);
SingleRoateLeft(k3);
}
//右左情况下的调整
void DoubleRoateRL(node* &k3)
{
SingleRoateLeft(k3->right);
SingleRoateRight(k3);
}
//在以p为根结点的树上,插入结点x
void InsertNode(node* &p, int x)
{
if(p == NULL) //如果是空树
{
p = new node(x);
return ;
}
if(x < p->value) //在左子树中插入
{
InsertNode(p->left,x);
//插入结点完成后,需要检查树是否平衡
if(2 == height(p->left) - height(p->right))
{
if(p->left->value > x)//左左
{
SingleRoateLeft(p);
}
else//左右
{
DoubleRoateLR(p);
}
}
}
else if(x > p->value) //在右子树上插入结点
{
InsertNode(p->right,x);
//插入结点完成后,需要检查树是否平衡
if(2 == height(p->right) - height(p->left))
{
if(p->right->value < x) //右右
{
SingleRoateRight(p);
}
else//右左
{
DoubleRoateRL(p);
}
}
}
else // x== p->value 不做处理
{
return;
}
p->height = max(height(p->left),height(p->right))+1;
}
//在以p为根节点的树上,删除结点,元素值为x
void DeleteNode(node* &p, int x)
{
if(p == NULL)//p为空树
return ;
if(x < p->value)//在左子树上删除
{
DeleteNode(p->left,x);
//删除完后,需要检查树的平衡性
if(2 == height(p->right) - height(p->left))
{
if(p->right->left && height(p->right->left) > height(p->right->right))
DoubleRoateRL(p);
else
SingleRoateRight(p);
}
}
else if(x > p->value)//在右子树上删除
{
DeleteNode(p->right,x);
//删除完后,需要检查树的平衡性
if(2 == height(p->left)-height(p->right))
{
if(p->left->right && height(p->left->right) > height(p->left->left))
DoubleRoateLR(p);
else
SingleRoateLeft(p);
}
}
else //找到了需要删除的结点,x == p->value
{
if(p->left && p->right) //有两个孩子,需要找后继结点,原理与二叉查找树一样
{
node* temp = p->right;
//找p的后继结点
while (temp->left)
{
temp = temp->left;
}
p->value = temp->value;//元素值的替换
DeleteNode(p->right,temp->value);//删除后继结点
if(2 == height(p->left)-height(p->right)) //删除完后,需要检查树的平衡
{
if(p->left->right && height(p->left->right) > height(p->left->left))
DoubleRoateLR(p);
else
SingleRoateLeft(p);
}
}
else//只有一个孩子或没有孩子,只需把指针关系调整下即可
{
node* temp = p;
if(p->left == NULL)
p = p->right;
else if(p->right == NULL)
p = p->left;
delete temp;
temp = NULL;
}
}
if(p == NULL)
return;
p->height = max(height(p->left),height(p->right))+1;
}
int _tmain(int argc, _TCHAR* argv[])
{
return 0;
}
二查平衡树的插入与删除(四种旋转)
最新推荐文章于 2021-10-22 15:55:55 发布