L3-010 是否完全二叉搜索树 (30 分)
将一系列给定数字顺序插入一个初始为空的二叉搜索树(定义为左子树键值大,右子树键值小),你需要判断最后的树是否一棵完全二叉树,并且给出其层序遍历的结果。
输入格式:
输入第一行给出一个不超过20的正整数N
;第二行给出N
个互不相同的正整数,其间以空格分隔。
输出格式:
将输入的N
个正整数顺序插入一个初始为空的二叉搜索树。在第一行中输出结果树的层序遍历结果,数字间以1个空格分隔,行的首尾不得有多余空格。第二行输出YES
,如果该树是完全二叉树;否则输出NO
。
输入样例1:
9
38 45 42 24 58 30 67 12 51
输出样例1:
38 45 24 58 42 30 12 67 51
YES
输入样例2:
8
38 24 12 45 58 67 42 51
输出样例2:
38 45 24 58 42 12 67 51
NO
根据完全二叉数的性质求解:
#include<iostream>
#include<vector>
using namespace std;
int main() {
int n, tmp, root, last = 0;
cin >> n;
vector<int> tree(1000000,-1);
for (int i = 0; i < n; i++) {
cin >> tmp;
root = 0;
while (tree[root] != -1) //根据二叉树的性质,左孩子下标为根节点*2+1,右孩子*2+2,,寻找插入点
root = tree[root] < tmp ? (root << 1) + 1 : (root << 1) + 2;
if (root > last) last = root; //记录最后下标
tree[root] = tmp;
}
for (int i = 0; i <= last; i++)
if (tree[i] != -1)
cout << (i ? " " : "") << tree[i];
cout << endl << (last < n ? "YES" : "NO");
return 0;
}
history:
判断完全二叉树:
什么是完全二叉树,按我的理解就是,一种残缺的满二叉树(最多就是底层右边可以缺少几个节点)。
如果我们在二叉树的外层补上一层空结点呢(将非空结点的左右孩子给补上)会发生什么呢?
好了,我就是这样判断的
推荐测试用例:
测试点2:5 5 7 4 8 6
测试点3:5 5 7 4 8 3
测试点7:2 2 1
#include<iostream>
#include<string>
#include<map>
#include<queue>
using namespace std;
struct Node {
int left=-1, right=-1;
};
map<int, Node> tree;
void insert(int head, int tmp,int height) { //构造搜索树
if (head != -1) {
int r = tmp > head ? tree[head].left : tree[head].right;
if (r != -1)
insert(r, tmp,height+1);
else
(tmp > head ? tree[head].left : tree[head].right) = tmp;
}
}
void traverse(int head) {
queue<int> q;
q.push(head);
int key = 0, empty = 0;
cout << head;
while (!q.empty()) {
if (q.front() != -1) {
q.push(tree[q.front()].left);
q.push(tree[q.front()].right);
if (empty) key = 1;
}
else empty = 1; //当出现空结点,后面的必须都是空结点
q.pop();
if(q.front()!=-1&&!q.empty()) //输出非空结点
cout <<" "<< q.front();
}
cout<<endl<<( key ? "NO" : "YES");
}
int main() {
int n, m, tmp, head;
string link, str;
cin >> n >> head;
for (int i = 1; i < n; i++) {
cin >> tmp;
insert(head, tmp, 1);
}
traverse(head);
return 0;
}