版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
写在前面
- 思路分析
- 判断是不是完全二叉树
- 出现1个孩⼦为空的结点之后是否还会出现孩子结点不为空的结点,如果出现就不是完全⼆叉树
- AVL树共四种情况,发现树不平衡的结点记为A结点, A发现树不不平衡的情况有四种:
- 新结点插入到A的左子树的左子树-
右旋
- 新结点插入到A的左子树的右子树-
A的左子树左旋,然后对A右旋
- 新结点插入到A的右子树的左子树-
A的右子树右旋,然后对A左旋
- 新结点插入到A的右子树的右子树-
左旋
- 新结点插入到A的左子树的左子树-
- 判断是不是完全二叉树
- 知识盲点,学习ing
- 难度较大,代码量较大
测试用例
-
input: 5 88 70 61 63 65 output: 70 63 88 61 65 YES input: 8 88 70 61 96 120 90 65 68 output: 88 65 96 61 70 90 120 68 NO
ac代码
-
#include <iostream> #include <vector> #include <queue> using namespace std; struct node { int val; struct node *left, *right; }; node* leftRotate(node *tree) { node *tmp = tree->right; tree->right = tmp->left; tmp->left = tree; return tmp; } node* rightRotate(node *tree) { node *tmp = tree->left; tree->left = tmp->right; tmp->right = tree; return tmp; } node* leftRightRotate(node *tree) { tree->left = leftRotate(tree->left); return rightRotate(tree); } node* rightLeftRotate(node *tree) { tree->right = rightRotate(tree->right); return leftRotate(tree); } int getHeight(node *tree) { if(tree == NULL) return 0; int l = getHeight(tree->left); int r = getHeight(tree->right); return max(l, r)+1; } node* inserts(node *tree, int val) { if(tree == NULL) { tree = new node(); tree->val = val; } else if(tree->val > val) { tree->left = inserts(tree->left, val); int l = getHeight(tree->left), r = getHeight(tree->right); if(l-r>=2) { if(val < tree->left->val) tree = rightRotate(tree); else tree = leftRightRotate(tree); } } else { tree->right = inserts(tree->right, val); int l=getHeight(tree->left), r = getHeight(tree->right); if(r-l >= 2) { if(val>tree->right->val) tree = leftRotate(tree); else tree = rightLeftRotate(tree); } } return tree; } int isComplete = 1, after = 0; vector<int> levelOrder(node *tree) { vector<int> v; queue<node *> queues; queues.push(tree); while(!queues.empty()) { node *tmp = queues.front(); queues.pop(); v.push_back(tmp->val); if(tmp->left != NULL) { if(after) isComplete = 0; queues.push(tmp->left); } else after = 1; if(tmp->right != NULL) { if(after) isComplete = 0; queues.push(tmp->right); } else after = 1; } return v; } int main() { int n, tmp; scanf("%d", &n); node *tree = NULL; for(int i=0; i<n; i++) { scanf("%d", &tmp); tree = inserts(tree, tmp); } vector<int> v = levelOrder(tree); for(int i=0; i<v.size(); i++) { if(i!=0) printf(" "); printf("%d", v[i]); } printf("\n%s", isComplete ? "YES" : "NO"); return 0; }
知识点小结
- AVL树知识点
- 左右子树都是AVL树
- AVL树中任何节点的两个子树的高度最大差别为1
- 左子树和右子树高度之差(简称平衡因子)的绝对值不超过1(-1、0、1)
- 查找
- 插入
- 左旋
- 右旋
- 情况汇总
- 判断是否是完全二叉树
- 如果树为空,则直接返回错
- 如果树不为空:层序遍历二叉树
- 如果1个结点左右孩子都不为空,则pop该节点,将其左右孩子入队列
- 如果遇到1个结点,左孩子为空,右孩子不为空,则该树一定不是完全二叉树
- 如果遇到1个结点,左孩子不为空,右孩子为空;或左右孩子都为空;则该节点之后队列中的结点都为叶子节点;该树才是完全二叉树,否则不是完全二叉树
- 如果1个结点左右孩子都不为空,则pop该节点,将其左右孩子入队列
- 二叉树层次遍历
- 构建1个队列 依次访问二叉树的头结点
- 判断头结点不为空然后进入
- 首先将根节点入队 从根节点判断左右子节点
- 然后出队队头元素
- 队列的作用就是将二叉树按照 根 左 右的顺序接收然后出队操作
- 最终队列为空的时候 跳出循环 达到层次遍历的目的