判断给定序列形成的完全二叉树是不是一颗二叉排序树
2019.3.29晚上,快手APP在线笔试一道编程题 “判断给定序列形成的完全二叉树是不是一颗二叉排序树”。当时只是用数组下标基于局部的判断。只能通过30%的用例。看了一位大佬的给定序列转为二叉树。原文链接,然后重新完善了一下这个代码。
思路如下:
1. 给定序列转为二叉树。
2. 将二叉树中序遍历所得到的序列保存在一个数组里。
3. 判断,如果是二叉排序树,则中序遍历出来的结果是一个升序数列,只需判断得到的序列是否是升序即可。
代码如下
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
struct Tree
{
Tree *lchild;
Tree *rchild;
int value;
};
void insert(Tree *p, vector<int> temp, int t)
{
int length = temp.size();
if (t >= length)
return;
p->value = temp[t];
if ((2 * (t + 1)) <= length)
{
if (temp[2 * (t + 1) - 1] != 0)
{
Tree *l;
l = (Tree *)malloc(sizeof(Tree));
l->lchild = NULL;
l->rchild = NULL;
p->lchild = l;
insert(p->lchild, temp, 2 * (t + 1) - 1);
}
if ((2 * (t + 1) + 1) <= length)
{
if (temp[2 * (t + 1)] != 0)
{
Tree *r;
r = (Tree *)malloc(sizeof(Tree));
r->lchild = NULL;
r->rchild = NULL;
p->rchild = r;
insert(p->rchild, temp, 2 * (t + 1));
}
}
}
}
Tree * Creat_From_Arr(vector<int> t)
{
Tree *p;
p = (Tree *)malloc(sizeof(Tree));
p->lchild = NULL;
p->rchild = NULL;
insert(p, t, 0);
return p;
}
void Creat_squence_by_inorder(Tree *p, int *count, int a[])
{
if (p != NULL)
{
Creat_squence_by_inorder(p->lchild, count, a);
a[(*count)++] = p->value;
Creat_squence_by_inorder(p->rchild, count, a);
}
}
bool is_BST(int *a, int n)
{
for (int i = 1; i < n; i++)
{
if (a[i] < a[i-1])
return false;
}
return true;
}
主函数如下
int main()
{
int n;
cin >> n;
vector<int> v(n);
int *a = new int(n);
int *b = new int(n);
for (int i = 0; i < n; i++)
{
cin >> v[i];
}
Tree *tree = Creat_From_Arr(v);
int integer = 0;
int *pos = &integer;
Creat_squence_by_inorder(tree, pos, a);
if (is_BST(a, *pos))
{
cout << "True";
return 0;
}
else
{
cout << "False";
return 0;
}
delete[]a;
}
(https://img-blog.csdnimg.cn/20190401072148201.png)
此案例的二叉树如下:
很明显上图的5,6节点不符合二叉树查找树定义,6是5的左子树,不应该比5大。
这个题的核心就是将给定序列转为二叉树,再将二叉树的中序遍历结果存放至数组里,要判断这个数组里面的数是不是严格升序,办法就很多了,简单起见就逐个判断。