平衡二叉树(AVL)的构造,插入与删除代码(利用递归)

创建AVL树并判断是否为完全二叉树

题目描述

在AVL树中,任何节点的两个子树的高度最多相差1;如果它们高度相差不止1,则需要重新平衡以恢复这种属性。
现在给定一个插入序列,
一个一个地将键值插入初始为空的AVL树中
输出得到的AVL树的层次顺序遍历序列
判断它是否是一个完全二叉树

输入格式:

第一行包含一个正整数N(<= 20)。然后在下一行给出N个不同的整数键。所有数字都用空格隔开。

输出格式:

第一行打印得到的AVL树的层次顺序遍历序列。所有数字都必须用空格隔开,并且行尾必须没有多余的空格。然后在下一行中,如果树为完全二叉树,则打印“Yes”;如果不是,则打印“No”。

样例1
输入:
5
88 70 61 63 65

输出:
70 63 88 61 65
Yes

样例2
输入:
10
62 88 58 47 35 73 51 99 37 93

输出:
62 47 88 35 58 73 99 37 51 93
No

此题目提出了平衡二叉树的创建与插入,下面代码实现了
同时也实现了avl删除的代码。

如何实现平衡二叉树的删除呢

#include<iostream>
#include<queue>
#include<algorithm>
using namespace std;
//树结点
struct TreeNode
{
  int val;
  int height;
  TreeNode* left;
  TreeNode*right;
  TreeNode():val(0),left(nullptr),right(nullptr),height(1){}
  TreeNode(int x):val(x),left(nullptr),right(nullptr),height(1){}
  TreeNode(int x,TreeNode*left,TreeNode*right):val(x),height(1),left(left),right(right){}
};

//某树是不是完全二叉树
bool isbinarytree(TreeNode*root)
{
  queue<TreeNode*>que;
  que.push(root);
  TreeNode *cur;
  //遇到空结点
  while((cur=que.front())!=nullptr)
  {
    que.pop();
    que.push(cur->left);
    que.push(cur->right);
  }
  //验证que里面还有没有数
  while(!que.empty())
  {
    if (que.front()!=nullptr)
    {
      return false;
    }
    que.pop();
  }
  return true;
}

//层次遍历输出数组
vector<int> levelorder(TreeNode*root)
{
  vector<int>arr;
  if (root)
  {queue<TreeNode*>que;
  que.push(root);
  while (!que.empty())
  {
    auto x=que.front();
    arr.push_back(x->val);
    que.pop();
    if (x->left)que.push(x->left);
    if (x->right)que.push(x->right);
  }
  }
  return arr;
}

//getheight(递归)
int getheight(TreeNode* root)
{
  if (!root)return 0;
  return root->height;
} 

//LL右单旋
TreeNode* rightrotate(TreeNode* root)
{
  TreeNode* temp=root->left;
  root->left=temp->right;
  temp->right=root;
  root->height=max(getheight(root->left),getheight(root->right))+1;
  temp->height=max(getheight(temp->left),getheight(temp->right))+1;
  return temp;
}

//RR左单旋
TreeNode* leftrotate(TreeNode* root)
{
  TreeNode* temp=root->right;
  root->right=temp->left;
  temp->left=root;
  root->height=max(getheight(root->left),getheight(root->right))+1;
  temp->height=max(getheight(temp->left),getheight(temp->right))+1;
  return temp;

}

//LR 对root->left做左单旋,再对root做右单旋
TreeNode* lerigrotate(TreeNode* root)
{
  root->left=leftrotate(root->left);
  return rightrotate(root);
}

//RL 对root-right做右单旋,再对root做左单旋
TreeNode* riglerotate(TreeNode* root)
{
  root->right=rightrotate(root->right);
  return leftrotate(root);
}

//把数据插入到avl树上
TreeNode* insert(TreeNode * root,int key)
{
  if (!root)
  {
   root=new TreeNode(key);
   return root;
  }
  else
  {
    if (key<root->val)
    {
      root->left=insert(root->left,key);
      if (getheight(root->left)-getheight(root->right)==2)
      {
        if (key<root->left->val)root=rightrotate(root);
        else root=lerigrotate(root);
      } 
    }
    else if(key>root->val)
    {
      root->right=insert(root->right,key);
      if (getheight(root->right)-getheight(root->left)==2)
      {
        if (key>root->right->val)root=leftrotate(root);
        else root=riglerotate(root);
      }
    }
  }
  root->height=max(getheight(root->left),getheight(root->right))+1;
  return root;
}

bool isdelete=1;
//删除叶子结点的方法删除avl结点
TreeNode* deletekey(TreeNode* root,int key)
{
  if (!root) {isdelete=0;return root;}//没成功删除
  if (root->val==key)//删除叶子结点
  {
    if(!root->left&&!root->right){root=nullptr;return root;}
    if (getheight(root->left)>=getheight(root->right))//替换并且使得要删除的元素变成叶子结点
        {
          //对左孩子找到最里面的右孩子,改变key,迭代删掉它
          TreeNode* temp=root->left;
          while (temp->right)
          {
            temp=temp->right;
          }
          root->val=temp->val;
          key=temp->val;
          root->left=deletekey(root->left,key);
          if (getheight(root->right)-getheight(root->left)==2)root=leftrotate(root);

        }
    else
        {
          TreeNode* temp=root->right;
          while (temp->left)
          {
            temp=temp->left;
          }
          root->val=temp->val;
          key=temp->val;
          root->right=deletekey(root->right,key);
          if (getheight(root->left)-getheight(root->right)==2)root=rightrotate(root);

        }
  }
  else if(key<root->val)
  {
    root->left=deletekey(root->left,key);
    if (getheight(root->right)-getheight(root->left)==2)root=leftrotate(root);
  }
  else if(key>root->val)
  {
    root->right=deletekey(root->right,key);
    if (getheight(root->left)-getheight(root->right)==2)root=rightrotate(root);
  }
  root->height=max(getheight(root->left),getheight(root->right))+1;
  return root;
}





int main()
{
  int n;
  cin >> n;
	TreeNode* root = NULL;
	for(int i = 1; i <= n; i++)
	{
		int x;
		cin >> x;
		root = insert(root, x);
	}
  
  vector<int>arr=levelorder(root);
  for (int i = 0; i < arr.size()-1; i++)cout<<arr[i]<<" ";
  cout<<arr[arr.size()-1]<<endl;
  
  if (isbinarytree(root))cout<<"Yes"<<endl;
  else cout<<"No"<<endl;
  
  int m;
  cin>>m;
  root=deletekey(root,m);
  
  if (isdelete)cout<<"删除成功"<<endl;
  else cout<<"删除失败"<<endl;
  

  arr=levelorder(root);
  for (int i = 0; i < arr.size()-1; i++)cout<<arr[i]<<" ";
  cout<<arr[arr.size()-1]<<endl;

  if (isbinarytree(root))cout<<"Yes"<<endl;
  else cout<<"No"<<endl;

  system ("pause");
  return 0;
}



  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值