平衡二叉树的实现与遍历(全过程)

平衡二叉树的实现:
代码实现过程踩过的坑总结:

  1. 把结构体定义成如下形式是不行的。(BitTree好像是二级指针不能放结构体里面)
    typedef struct BitNode{
    int data;
    int bf;
    BitTree left;
    BitNode* right;
    }BitNode,*BitTree;
  2. malloc只能赋给结构体指针,不能赋给结构体(一直以为结构体和数组一样,名字代表指针,所以会犯错)。
  3. 插入函数设计时,应该设计成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

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页