PTA跳转:原题链接
这题考查AVL树,按层输出,判断一棵树是否为完全二叉树。这题是对A1066的改进(A1066解决的是AVL树)。
用一个队列即可实现按层输出,当某个结点出队之前,让它的左右孩子入队(如果有的话),直到队列为空。每个结点可能会出现4种情况:
①左右孩子都存在。么在当前结点出队之前,让左右孩子入队。
②只有左孩子。在当前结点出队之前,让左孩子入队。并将flag设为0,表示队列后续结点不应该再有孩子结点。
③只有右孩子。在当前结点出队之前,让右孩子入队。直接判断这棵树不是完全二叉树。
④左右孩子都为空。将当前结点出队,并将flag设为0,表示队列后续结点不应该再有孩子结点。
#include <iostream>
#include <queue>
using namespace std;
struct node {
int val;
struct node *left, *right;
};
node *rotateLeft(node *root) { //左旋(在根的右孩子的右孩子处插入结点时使用)
node *t = root->right; //1.原根的右孩子成为新根
root->right = t->left; //2.原根的右孩子的左孩子成为原根的右孩子
t->left = root; //3.原根成为新根的左孩子
return t; //4.返回新根
}
node *rotateRight(node *root) { //右旋(在根的左孩子的左孩子处插入结点时使用)
node *t = root->left;
root->left = t->right;
t->right = root;
return t;
}
node *rotateLeftRight(node *root) { //先左旋再右旋(在根的左孩子的右孩子处插入结点时使用)
root->left = rotateLeft(root->left); //1.以原根的左孩子为根进行左旋
return rotateRight(root); //2.原根进行右旋,返回新根
}
node *rotateRightLeft(node *root) { //先右旋再左旋(在根的右孩子的左孩子处插入结点时使用)
root->right = rotateRight(root->right);
return rotateLeft(root);
}
int getHeight(node *root) { //计算节点深度
if(root == NULL) return 0;
return max(getHeight(root->left), getHeight(root->right)) + 1;
}
node *insert(node *root, int val) { //插入元素
if(root == NULL) { //树无元素
root = new node();
root->val = val;
root->left = root->right = NULL;
} else if(val < root->val) { //往树根的左孩子处插入元素
root->left = insert(root->left, val);
if(getHeight(root->left) - getHeight(root->right) == 2)
root = val < root->left->val ? rotateRight(root) /*LL插入*/: rotateLeftRight(root); /*LR插入*/
} else {
root->right = insert(root->right, val);
if(getHeight(root->left) - getHeight(root->right) == -2)
root = val > root->right->val ? rotateLeft(root) /*RR插入*/: rotateRightLeft(root); /*RL插入*/
}
return root; //LR插入:在根的左孩子的右孩子处插入元素
}
int flag_isComplete = 1; //默认是完全二叉树
int isComplete() { //判断是否为完全二叉树
if (flag_isComplete)
return 1;
else
return 0;
}
void LayerPrint(node* root) {
int flag = 1; //判断是否为完全二叉树
queue<node*> q;
q.push(root);
cout << root->val; //入队时输出
while (q.size() != 0) //队伍不为空
{
if (q.front()->left != NULL && q.front()->right != NULL) { //左右孩子都不为空
if(flag == 0)
flag_isComplete = 0;
q.push(q.front()->left);
q.push(q.front()->right);
cout << " " << q.front()->left->val << " " << q.front()->right->val;
q.pop();
} else if (q.front()->left != NULL && q.front()->right == NULL) { //只有左孩子
if(flag == 0)
flag_isComplete = 0;
q.push(q.front()->left);
cout << " " << q.front()->left->val;
q.pop();
flag = 0; //如果队列后续元素不都是叶子节点,这棵树就不是完全二叉树
} else if (q.front()->left == NULL && q.front()->right != NULL) { //只有右孩子
q.push(q.front()->right);
cout << " " << q.front()->right->val;
q.pop();
flag_isComplete = 0; //只要出现某结点只有右孩子,这棵树肯定不是完全二叉树
} else { //叶子结点
q.pop();
flag = 0; //如果队列后续元素不都是叶子节点,这棵树就不是完全二叉树
}
}
}
int main() {
int n, val;
cin >> n;
node *root = NULL;
for (int i = 0; i < n; i++) {
cin >> val;
root = insert(root, val);
}
LayerPrint(root); //按层输出
if (isComplete())
cout << endl << "YES";
else
cout << endl << "NO";
return 0;
}
氷鸢鸢鸢
2020.7.16