给出一个数据序列,建立二叉排序树,并实现查找功能
对二叉排序树进行中序遍历,可以得到有序的数据序列
第一行输入t,表示有t个数据序列
第二行输入n,表示首个序列包含n个数据
第三行输入n个数据,都是自然数且互不相同,数据之间用空格隔开
第四行输入m,表示要查找m个数据
从第五行起,输入m行,每行一个要查找的数据,都是自然数
以此类推输入下一个示例
第一行输出有序的数据序列,对二叉排序树进行中序遍历可以得到
从第二行起,输出查找结果,如果查找成功输出查找次数,如果查找失败输出-1
以此类推输出下一个示例的结果
Copy
1 6 22 33 55 66 11 44 7 11 22 33 44 55 66 77
Copy
11 22 33 44 55 66 2 1 2 4 3 4 -1
这里我的想法是与查找一样的,从根节点开始比较,然后每次遇到一个节点与他的值相比较,小的话就往左子树走,大的话就往右子树走。
构建二叉树的时候,那肯定是插入一个新节点,那肯定那个节点插入之前是空的,所以找到符号位置条件的空节点就好啦!
假设有22 11 33 三个数据,要构建一个平衡树:
1.选择第一个为根节点,22为根节点
2.插入数据11,11<22,所以往左子树走,然后遇到空值,就在这插入
4.这时候可能疑惑如果又要往左子树走,又要往右子树走的呢?
这里我们假设插入13,13<22,往左子树走,
然后13>11,13往右子树走,遇到空值,这个位置就是适合13插入的点
2.建立树,其中分为两步,第一步构建根节点
ss队列是我用来存输入的数据,这样可以按顺序取
因为我这里先创建了根节点,然后插入的时候每次传了root根节点进去,然后insert()函数里面会改变节点状态,所以为了让改变起作用,需要用到引用
void insert(nod*& root, int val);
1.这里用到其实跟插入的思想一样,比这个节点小就往左走,比这个节点大就往右走
2.本题需要计算查找的时候需要的次数,所以我们可以传一个times进去,初始为1,因为进去就有个判断是否与根节点相等,也是一次查找
3.若根节点与值不相等,就按大小去递归查找,查找一次次数就+1
有点dfs计算高度那个味道了
#include
#include
using namespace std;
struct nod///树节点
{
int val;///节点的值
nod* left, * right;///节点的左右子树指针
nod()
{
left = NULL;
right = NULL;
}
nod(int x)
{
val = x;
left = NULL;
right = NULL;
}
};
queuess;
void insert(nod*& root, int val)
{
if (root == NULL)///先看下面两个if 2,3
{
root = new nod(val);///我们经历了下面的两个if里的递归会走到一个合适的空节点,这个时候插入这个val
return;
}
///2
if (val < root->val)///如果val的值小于这个节点的值,那就要往左子树走,然后利用递归
{
insert(root->left, val);///往左子树走插入
}
///3
if (val > root->val)///如果val的值大于这个节点的值,那就要往右子树走,然后利用递归
{
insert(root->right, val);///往右子树走插入
}
}
nod* buildtree()///构建树的代码
{
if (ss.empty())///这里是判断是否有数据可以构建树
return NULL;
nod* root;///构建根节点
root = new nod(ss.front());///序列的第一个数作为根节点
ss.pop();
while (!ss.empty())///判断是否还有可以插入的数据
{
int val = ss.front();///按顺序取数据
ss.pop();
insert(root, val);///插入进树里
}
return root;
}
void zhonxu(nod* root)
{
if (root == NULL)
return;
zhonxu(root->left);
cout << root->val << " ";
zhonxu(root->right);
}
int search(nod* root, int num, int times)
{
if (root == NULL)///遇到空节点就是没有找到就返回-1
return -1;
if (root->val == num)///节点值相等就返回查找次数
return times;
if (num < root->val)///查找值小于节点值
{
return search(root->left, num, times + 1);///往左子树查找,且查找次数+1
}
if (num > root->val)///查找值大于节点值
{
return search(root->right, num, times + 1);///往右子树查找,且查找次数+1
}
}
int main()
{
int t;
cin >> t;
while (t--)
{
int n;
cin >> n;
for (int i = 1; i <= n; i++)
{
int num;
cin >> num;
ss.push(num);///将所有数据放入队列里方便按顺序取出
}
nod* root = buildtree();///构建查找二叉树
zhonxu(root);///本题需要输出一次中序遍历,也可以用来检验你的树建立的对不对
cout << endl;
int t;
cin >> t;//查找数据次数
while (t--)
{
int num;
cin >> num;///查找的值
int times = 1;
times = search(root, num, times);///查找num需要用到多少次times
cout << times << endl;///输出查找num需要的次数
}
}
return 0;
}
今天的分享就到这啦!
晚安晚安晚安晚安!!!!!!