大一学生,写的肯定一般般,作为参考看一下吧,欢迎指出代码问题。只写了插入,删除还没有写。
#include<iostream>
using namespace std;
typedef int KeyType;
typedef struct VALNode
{
KeyType key;
VALNode* lchild, * rchild, * parent;
int deep;
}VALNode;
//声明函数:
VALNode* insertVAL(VALNode*& tree, KeyType k);
VALNode* FindUnbalance(VALNode* n);
int Judge(VALNode* p, VALNode* s);
void LL_turn(VALNode*& nodeA);
void RR_turn(VALNode*& nodeA);
void LR_turn(VALNode*& nodeA);
void RL_turn(VALNode*& nodeA);
bool SearchVAL(VALNode* bt, VALNode* n);
void ChangeHeight(VALNode*& n);
VALNode* GetRoot(VALNode* n);
void GetHeight(VALNode*& n);
//insert a node into the tree, return the root of the tree after inserting
VALNode* insertVAL(VALNode*& tree, KeyType k)
{
//tree是空树,建一颗树返回
if (tree == NULL)
{
tree = (VALNode*)malloc(sizeof(VALNode));
tree->key = k;
tree->deep = 0;
tree->lchild = tree->rchild = tree->parent = NULL;
return tree;
}
//移动到要插入的位置
VALNode* p = tree;
VALNode* pre = tree;
while (p != NULL)
{
pre = p;
if (p->key < k)
{
p = p->rchild;
}
else
{
p = p->lchild;
}
}
//创建一个节点
VALNode* node = (VALNode*)malloc(sizeof(VALNode));
node->key = k;
node->deep = 0;
node->lchild = node->rchild = node->parent = NULL;
//插入
if (node->key < pre->key)
{
pre->lchild = node;
}
else
{
pre->rchild = node;
}
node->parent = pre;
//改变平衡因子(高度)
ChangeHeight(node);
//看看有没有失衡
VALNode* unba = FindUnbalance(node);
if (unba != NULL)
{
//怎么调整
int how = Judge(unba, node);
switch (how)
{
case 0:
LL_turn(unba);break;
case 1:
RR_turn(unba);break;
case 2:
LR_turn(unba);break;
case 3:
RL_turn(unba);break;
}
//再次计算高度,以新的根节点为起点往下调整
tree = GetRoot(unba);
GetHeight(tree);
}
return tree;
}
//计算树n的所有节点高度
void GetHeight(VALNode*& n)
{
if (n->lchild == NULL && n->rchild == NULL)
{
ChangeHeight(n);
return;
}
if (n->lchild != NULL)
{
GetHeight(n->lchild);
}
if (n->rchild != NULL)
{
GetHeight(n->rchild);
}
}
//插入节点后改变相关节点高度,传入插入的节点的指针
void ChangeHeight(VALNode*& n)
{
n->deep = 0;
VALNode* p = n->parent;
while (p != NULL)
{
int ldeep = p->lchild == NULL ? -1 : p->lchild->deep;//左子树高度
int rdeep = p->rchild == NULL ? -1 : p->rchild->deep;//左子树高度
p->deep = (ldeep > rdeep ? ldeep : rdeep) + 1;//p.deep=左子树和右子树较大者+1
p = p->parent;
}
}
//找失衡节点,没有就返回null
VALNode* FindUnbalance(VALNode* n)//n是插入节点的位置,从n往根节点找
{
int ldeep = n->lchild == NULL ? -1 : n->lchild->deep;//左子树高度
int rdeep = n->rchild == NULL ? -1 : n->rchild->deep;//左子树高度
int df = ldeep - rdeep;//平衡因子df=左子树高度-右子树高度
if (df < -1 || df>1)
{
//该节点失衡
return n;
}
//向根节点方向找
if (n->parent != NULL)
{
return FindUnbalance(n->parent);
}
else
{
return NULL;
}
}
//判断要进行哪种调整
int Judge(VALNode* p, VALNode* s)//传入失衡节点和插入节点
{
if (SearchVAL(p->lchild, s))
{
if (SearchVAL(p->lchild->lchild, s))
{
//ll
return 0;
}
else
{
//lr
return 2;
}
}
else
{
if (SearchVAL(p->rchild->rchild, s))
{
//rr
return 1;
}
else
{
//rl
return 3;
}
}
}
//LL型调整0
void LL_turn(VALNode*& nodeA)//nodeA是第一个失衡节点,即调整子树的根节点
{
VALNode* nodeB = nodeA->lchild;
nodeA->lchild = nodeB->rchild;//b的右节点改成a的左节点
if (nodeB->rchild != NULL)
{
nodeB->rchild->parent = nodeA;
}
nodeB->rchild = nodeA;//a作为b的右节点
VALNode* Aparent = nodeA->parent;
nodeB->parent = Aparent;
if (Aparent != NULL)
{
if (Aparent->lchild == nodeA)
Aparent->lchild = nodeB;
else
Aparent->rchild = nodeB;
}
nodeA->parent = nodeB;
}
//RR型调整1
void RR_turn(VALNode*& nodeA)//nodeA是第一个失衡节点,即调整子树的根节点
{
VALNode* nodeB = nodeA->rchild;
nodeA->rchild = nodeB->lchild;//b的左节点改成a的右节点
if (nodeB->lchild != NULL)
{
nodeB->lchild->parent = nodeA;
}
nodeB->lchild = nodeA;//a作为b的左节点
VALNode* Aparent = nodeA->parent;
nodeB->parent = Aparent;
if (Aparent != NULL)
{
if (Aparent->lchild == nodeA)
Aparent->lchild = nodeB;
else
Aparent->rchild = nodeB;
}
nodeA->parent = nodeB;
}
//LR型调整2
void LR_turn(VALNode*& nodeA)//nodeA是第一个失衡节点,即调整子树的根节点
{
VALNode* nodeB = nodeA->lchild;
VALNode* nodeC = nodeB->rchild;
nodeB->rchild = nodeC->lchild;//c的lchild改成b的rchild
if (nodeC->lchild != NULL)
{
nodeC->lchild->parent = nodeB;
}
nodeA->lchild = nodeC->rchild;//c的rchild改成a的lchild
if (nodeC->rchild != NULL)
{
nodeC->rchild->parent = nodeA;
}
nodeC->lchild = nodeB;//c改成根节点
nodeC->rchild = nodeA;
VALNode* Aparent = nodeA->parent;
nodeC->parent = Aparent;
if (Aparent != NULL)
{
if (Aparent->lchild == nodeA)
Aparent->lchild = nodeC;
else
Aparent->rchild = nodeC;
}
nodeA->parent = nodeC;
nodeB->parent = nodeC;
}
//RL型调整3
void RL_turn(VALNode*& nodeA)//nodeA是第一个失衡节点,即调整子树的根节点
{
VALNode* nodeB = nodeA->rchild;
VALNode* nodeC = nodeB->lchild;
nodeA->rchild = nodeC->lchild;//c的lchild改成a的rchild
if (nodeC->lchild != NULL)
{
nodeC->lchild->parent = nodeA;
}
nodeB->lchild = nodeC->rchild;//c的rchild改成b的lchild
if (nodeC->rchild != NULL)
{
nodeC->rchild->parent = nodeB;
}
nodeC->lchild = nodeA;//c改成根节点
nodeC->rchild = nodeB;
VALNode* Aparent = nodeA->parent;
nodeC->parent = Aparent;
if (Aparent != NULL)
{
if (Aparent->lchild == nodeA)
Aparent->lchild = nodeC;
else
Aparent->rchild = nodeC;
}
nodeA->parent = nodeC;
nodeB->parent = nodeC;
}
//在树上查找节点n。找到返回true,否则返回false
bool SearchVAL(VALNode* bt, VALNode* n)
{
if (bt == NULL)
{
return false;
}
if (bt == n)
{
return true;
}
if (n->key < bt->key)
{
return SearchVAL(bt->lchild, n);
}
else
{
return SearchVAL(bt->rchild, n);
}
}
//得到根节点,调整完树后根节点可能会乱,用这个函数找到根节点
VALNode* GetRoot(VALNode* n)
{
if (n->parent == NULL)
return n;
return GetRoot(n->parent);
}
int main()
{
VALNode* tree = NULL;
insertVAL(tree, -1);
insertVAL(tree, 2);
insertVAL(tree, 5);//RR
insertVAL(tree, -2);
insertVAL(tree, -3);//LL
insertVAL(tree, 4);
insertVAL(tree, 3);//RL
insertVAL(tree, 0);
insertVAL(tree, 1);//LR
return 0;
}
附上主函数测试数据最后形成的树: