平衡二叉树的实现:
代码实现过程踩过的坑总结:
- 把结构体定义成如下形式是不行的。(BitTree好像是二级指针不能放结构体里面)
typedef struct BitNode{
int data;
int bf;
BitTree left;
BitNode* right;
}BitNode,*BitTree; - malloc只能赋给结构体指针,不能赋给结构体(一直以为结构体和数组一样,名字代表指针,所以会犯错)。
- 插入函数设计时,应该设计成InsertAVL(BitTree* T,int data,bool &taller),这样不行:InsertAVL(BitTree T,int data,bool &taller)。函数在在进入函数后,相当于形参,回传不了。
//平衡二叉树的基本操作实现代码
#include<iostream>
#include<stack>
using namespace std;
//宏定义标识两边高度差,LH左边高,EH平衡,RH右边高
#define LH +1
#define EH 0
#define RH -1
//树节点定义
typedef struct BitNode{
int data;
int bf;
BitNode* left;
BitNode* right;
}BitNode,*BitTree;
//插入节点后左旋
void L_Rotate(BitTree* T){
BitTree R=(*T)->right;
(*T)->right=R->left;
R->left=(*T);
(*T)=R;
return ;
}
//插入节点后右旋
void R_Rotate(BitTree* T){
BitNode* L=(*T)->left;
(*T)->left=L->right;
L->right=(*T);
(*T)=L;
return ;
}
//T 的左边高,不平衡,使其平衡,右旋转,右旋转前先检查L->bf,
//如果为RH,L要先进行左旋转,使T->left->bf和T->bf一致
void LeftBalance(BitTree* T){
BitTree L=(*T)->left;
switch(L->bf){
case LH:
(*T)->bf=EH;
L->bf=EH;
R_Rotate(T);
break;
case RH:
BitTree LR=L->right;
switch (LR->bf)
{
case LH:
(*T)->bf=RH;
L->bf=EH;
break;
case EH:
(*T)->bf=EH;
L->bf=EH;
break;
case RH:
(*T)->bf=EH;
L->bf=LH;
break;
}
LR->bf=EH;
L_Rotate(&L);
R_Rotate(T);
break;
}
}
//T 的右边高,不平衡,使其平衡,左旋转,左旋转前先检查R->bf,
//如果为LH,R要先进行右旋转,使T->left->bf和T->bf一致
void RightBalance(BitTree* T){
BitTree R=(*T)->right;
switch (R->bf)
{
case RH:
(*T)->bf=R->bf=EH;
L_Rotate(T);
break;
case LH:
BitTree RL=R->left;
switch (RL->bf)
{
case LH:
(*T)->bf=EH;
R->bf=RH;
break;
case EH:
(*T)->bf=EH;
R->bf=EH;
break;
case RH:
(*T)->bf=LH;
R->bf=EH;
break;
}
RL->bf=EH;
R_Rotate(&R);
L_Rotate(T);
break;
}
}
//往平衡二叉树上插入结点
bool InsertAVL(BitTree* T,int data,bool &taller){
if((*T)==NULL){//找到了插入的位置
(*T)=(BitNode*)malloc(sizeof(BitNode));
(*T)->data=data;
(*T)->left=(*T)->right=NULL;
(*T)->bf=EH;
taller=true;
}else{
if(data==((*T)->data)){
taller=false;
return false;
}
if(data<((*T)->data)){
if(!InsertAVL(&(*T)->left,data,taller)){
taller=false;
return false;
}
if(taller){
switch((*T)->bf){
case LH:
LeftBalance(T); //插入后左边不平衡了,让其左平衡
taller = false;
break;
case EH:
(*T)->bf = LH;
taller = true;
break;
case RH:
(*T)->bf = EH;
taller = false;
break;
}
}
}else{
if(!InsertAVL(&(*T)->right,data,taller)) //树中有相同的结点
{
taller = false;
return false;
}
if (taller) //插入到右子树中且长高了
{
switch ((*T)->bf) //T插入结点后,检测平衡因子,根据情况,做相应的修改和旋转
{
case LH:
(*T)->bf = EH;
taller = false;
break;
case EH:
(*T)->bf = RH;
taller = true;
break;
case RH:
RightBalance(T); //插入后右边不平衡了,让其右平衡
taller = false;
break;
}
}
}
}
return true;
}
//先序遍历
void PreOrder(BitNode* BitNode){
if(BitNode!=NULL){
cout<<BitNode->data<<" ";
PreOrder(BitNode->left);
PreOrder(BitNode->right);
}
}
void SqlPreOrder(BitTree T)//先序非递归遍历
{
stack<BitTree> s;
BitTree p=T;
while(p || !s.empty())
{
if(p)
{
cout<<p->data<<" ";
s.push(p);
p=p->left;
}
else
{
p=s.top();
p=p->right;
s.pop();
}
}
}
//中序遍历
void InOrder(BitNode* BitNode){
if(BitNode!=NULL){
InOrder(BitNode->left);
cout<<BitNode->data<<" ";
InOrder(BitNode->right);
}
}
void SqlInOrder(BitTree T)//中序非递归遍历
{
stack<BitTree> s;
BitTree p=T;
while(p || !s.empty())
if(p)
{
s.push(p);
p=p->left;
}
else
{
p=s.top();
cout<<p->data<<" ";
s.pop();
p=p->right;
}
}
//后序遍历
void PostOrder(BitNode* BitNode){
if(BitNode!=NULL){
PostOrder(BitNode->left);
PostOrder(BitNode->right);
cout<<BitNode->data<<" ";
}
}
void SqlPostOrder(BitTree T)//后序非递归遍历1
{
stack<BitTree> s;
BitTree p=T,r;
while(p || !s.empty())
{
if(p) //走到最左边
{
s.push(p);
p=p->left;
}
else //向右
{
p=s.top();//取栈顶结点
if(p->right && p->right!=r)//如果右子树存在,且未被访问过
{
p=p->right;
s.push(p);
p=p->left; //再走到最左
}
else //否则,访问栈顶结点并弹出
{
cout<<p->data<<" ";
r=p; //记录该结点
s.pop();
p=NULL; //结点访问完后,重置p指针
}
}
}
}
void FreeBitNode(BitNode* BitNode){
if(BitNode==NULL){
return;
}
if((BitNode->left==NULL)&&(BitNode->right==NULL)){
free(BitNode);
BitNode=NULL;
return ;
}
if(BitNode->left!=NULL){
FreeBitNode(BitNode->left);
}
if(BitNode->right!=NULL){
FreeBitNode(BitNode->right);
}
}
bool FindNode(BitNode* Tree,int val){
if(Tree==NULL){
return false;
}
if(Tree->data==val){
return true;
}else if(Tree->data>val){
return FindNode(Tree->left,val);
}else{
return FindNode(Tree->right,val);
}
}
//删除节点
bool DeleteNode(BitTree *T, int val,bool &taller) {
if ((*T) == NULL) {
return false;
}
else if (val == (*T)->data) {
BitTree temp = NULL;
if ((*T)->left == NULL) {
temp = (*T);
(*T) = (*T)->right;
free(temp);
taller = true;
}
else if ((*T)->right == NULL) {
temp = (*T);
(*T) = (*T)->left;
free(temp);
taller = true;
}
else {
temp = (*T)->left;
while (temp->right) {
temp = temp->right;
}
(*T)->data = temp->data;
DeleteNode(&(*T)->left, temp->data, taller);
}
}
else if (val < (*T)->data) {
if (!DeleteNode(&(*T)->left, val, taller)) {
return false;
}
if (taller) {
switch ((*T)->bf)
{
case LH:
(*T)->bf = EH;
taller = true;
break;
case RH:
RightBalance(T);
if ((*T)->right->bf == EH) {
taller = false;
}
else {
taller = true;
}
break;
case EH:
(*T)->bf = RH;
taller = false;
break;
}
}
}
else {
if (!DeleteNode(&(*T)->right, val, taller)) {
return false;
}
if (taller) {
switch ((*T)->bf)
{
case LH:
LeftBalance(T);
if ((*T)->left->bf == EH) {
taller = false;
}
else {
taller = true;
}
break;
case EH:
(*T)->bf = LH;
taller = false;
break;
case RH:
(*T)->bf = EH;
taller = true;
break;
}
}
}
return true;
}
int main(){
BitNode* BitNode=NULL;
int a[9]={2,3,2,4,4,6,8,3,84};
bool taller=true;
for(int i=0;i<9;i++){
//cout<<"null point"<<endl;
InsertAVL(&BitNode,a[i],taller);
taller=true;
}
if(BitNode!=NULL){
//使用递归方法实现树的先序,中序,后序遍历
cout<<"<--使用递归方法实现树的先序,中序,后序遍历-->"<<endl;
PreOrder(BitNode);
cout<<endl;
InOrder(BitNode);
cout<<endl;
PostOrder(BitNode);
cout<<endl<<endl;
//使用栈实现树的先序,中序,后序遍历
cout<<"<--使用栈实现树的先序,中序,后序遍历-->"<<endl;
SqlPreOrder(BitNode);
cout<<endl;
SqlInOrder(BitNode);
cout<<endl;
SqlPostOrder(BitNode);
cout<<endl<<endl;
}else{
cout<<"null point"<<endl;
}
taller=false;
if(FindNode(BitNode,2)){
cout<<"OK,节点2存在"<<endl;
}
DeleteNode(&BitNode,2,taller);
if(!FindNode(BitNode,2)){
cout<<"OK,节点2已经被删除"<<endl;
}
cout<<endl<<"-----检查2节点是否删除?"<<endl;
PreOrder(BitNode);
FreeBitNode(BitNode);
system("pause");
return 0;
}
资料参考:https://blog.csdn.net/qq_29542611/article/details/80136574
https://blog.csdn.net/weixin_42154649/article/details/80831573