创建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;
}