0.简介
删除平衡二叉树的结点也需要仔细的研究一下。还有代码上对上一篇打了些补丁
1.删除
删除结点后的结构一般有两种,一类是删除后不平衡了,一类是删除后仍然平衡。这两类别目前对我们来说,没有什么区别,因为前面已经研究过结点平衡调整的方法,所以可以直接在这里使用,那么需要研究的就是如何删除结点。
我们先从链表的角度来看,链表删除比较容易,改变指向下一个结点的指针就好,一般来说,改变一个就可以。

二叉树来说,删除就麻烦了一些,要有两个指针需要变化,链表只需要考虑下一个元素怎么连接上就好,树要考虑子节点谁来连接。

我们考虑让子节点的任意一个来接替位置,我们就一律让右边的结点来接替父节点的位置,左节点保持不动,若没有右结点,在去升左结点的位置。

结点换位就要调整指针,这里为了方便,可以用另一种办法,先考虑如下问题,如何删除单链表中指针正在指向的元素,不需要额外变量,只需要将当前结点的下一个结点的内容复制过来,然后删除下一个结点即可。树中我也这么做。
删除的流程如下
1.找到要删除的结点
2.将其删除,并且移动相关结点数据
3.查看树是否保持平衡,不平衡则调整。
2.实现
#include<iostream>
#include <algorithm>
using namespace std;
struct TreeNode
{
TreeNode(){}
TreeNode(int n,int h):num(n),height(h) {}
int num = 0;
int height = 0;
TreeNode* left = nullptr;
TreeNode* right = nullptr;
TreeNode* parent = nullptr;
};
inline int getHeight(TreeNode* root)
{
return root ? root->height : 0;
}
//调整平衡后树高度
void adjustHeight(TreeNode*T)
{
if (T->left != nullptr && T->right != nullptr)
T->height = max(T->left->height + 1, T->right->height + 1);
else if (T->left != nullptr)
T->height = T->left->height + 1;
else if (T->right != nullptr)
T->height = T->right->height + 1;
else
T->height = 1;
}
void condition1(TreeNode*& root)
{
/* A
/
B
/
C
*/
TreeNode* A = root;
TreeNode* B = root->left;
A->left = B->right;
B->parent = A->parent;
A->parent = B;
B->right = A;
root = B;
//重新计算平衡后,被调整结点的高度记录
adjustHeight(A);
adjustHeight(B);
}
void condition2(TreeNode*& root)
{
/*A
\
B
\
C
*/
TreeNode* A = root;
TreeNode* B = root->right;
A->right = B->left;
B->parent = A->parent;
A->parent = B;
B->left = A;
root = B;
adjustHeight(A);
adjustHeight(B);
}
void condition3(TreeNode*& root)
{
/* A
/
B
\
C
*/
TreeNode* A = root;
TreeNode* B = root->left;
TreeNode* C = root->left->right;
A->left = C->right;
B->right = C->left;
C->left = B;
C->right = A;
C->parent = A->parent;
B->parent = C;
A->parent = A;
root = C;
adjustHeight(A);
adjustHeight(B);
adjustHeight(C);
}
void condition4(TreeNode*& root)
{
/* A
\
B
/
C
*/
TreeNode* A = root;
TreeNode* B = root->right;
TreeNode* C = root->right->left;
A->right = C->left;
B->left = C->right;
C->right = B;
C->left = A;
C->parent = A->parent;
B->parent = C;
A->parent = A;
root = C;
adjustHeight(A);
adjustHeight(B);
adjustHeight(C);
}
int addNode(TreeNode* &root,int num)
{
//如果节点的空
if (root == nullptr)
{
//创建节点
root = new TreeNode(num,1);
//返回树高
return 1;
}
int lHeight = getHeight(root->left), rHeight = getHeight(root->right);
//左子树
if (num < root->num)
{
//添加节点
lHeight = addNode(root->left, num);
//修改父节点
root->left->parent = root;
}
//右子树
else
{
//添加节点
rHeight = addNode(root->right, num);
//修改父节点
root->right->parent = root;
}
//调整树
if (abs(lHeight - rHeight) > 1)
{
if (lHeight> rHeight)
{
if (getHeight(root->left->left) > getHeight(root->left->right))
condition1(root);
else
condition3(root);
}
else
{
if (getHeight(root->right->right) > getHeight(root->right->left))
condition2(root);
else
condition4(root);
}
}
lHeight = getHeight(root->left);
rHeight = getHeight(root->right);
return root->height = max(lHeight , rHeight) + 1;
}
int moveNode(TreeNode*& root)
{
if (root == nullptr)
return 0;
TreeNode*& parent = root;
int lHeight = getHeight(root->left), rHeight = getHeight(root->right);
if (root->left != nullptr || root->right != nullptr)
{
//将右边提上来,没有右边就提左边
if (root->right != nullptr)
{
root->num = root->right->num;
rHeight = moveNode(root->right);
}
else if (root->left != nullptr)
{
root->num = root->left->num;
lHeight = moveNode(root->left);
}
return root->height = max(rHeight, lHeight) + 1;
}
else
{
//删除parent
if (parent != nullptr)
{
delete parent;
parent = nullptr;
return 0;
}
}
}
int deleteNode(TreeNode*& root, int num)
{
if (root == nullptr)
return 0;
//删除
TreeNode* parent = nullptr;
//获取当前树的高度
int lHeight = getHeight(root->left), rHeight = getHeight(root->right);
if (num > root->num)
rHeight = deleteNode(root->right,num);
else if (num < root->num)
lHeight = deleteNode(root->left, num);
else if (root->num == num)
moveNode(root);
//调整树
if (abs(lHeight - rHeight) > 1)
{
if (lHeight > rHeight)
{
if (getHeight(root->left->left) > getHeight(root->left->right))
condition1(root);
else
condition3(root);
}
else
{
if (getHeight(root->right->right) > getHeight(root->right->left))
condition2(root);
else
condition4(root);
}
}
//重新计算树的高度
if (root != nullptr)
{
lHeight = getHeight(root->left);
rHeight = getHeight(root->right);
return root->height = max(lHeight, rHeight) + 1;
}
else
{
lHeight = 0;
rHeight = 0;
return 0;
}
}
int main()
{
TreeNode* root = nullptr;
addNode(root,12);
addNode(root, 5);
addNode(root, 15);
addNode(root,3);
addNode(root, 8);
addNode(root, 9);
addNode(root, 6);
addNode(root, 20);
//addNode(root, 21);
deleteNode(root, 20);
deleteNode(root, 15);
deleteNode(root, 9);
deleteNode(root, 12);
deleteNode(root, 3);
return 0;
}