二叉搜索树
定义
二叉查找树(英语:Binary Search Tree),也称为二叉搜索树、有序二叉树(ordered binary tree)或排序二叉树(sorted binary tree),是指一棵空树或者具有下列性质的二叉树:
- 若任意节点的左子树不空,则左子树上所有节点的值均小于它的根节点的值;
- 若任意节点的右子树不空,则右子树上所有节点的值均大于或等于它的根节点的值;
- 任意节点的左、右子树也分别为二叉查找树;
推荐讲解视频:
https://www.bilibili.com/video/BV1Qx411m7Lb
https://www.bilibili.com/video/BV1Qx411m7jE
https://www.bilibili.com/video/BV1os411Y7Rt正月点灯笼@BILIBILI
形式与基本性质
满二叉树:
在一棵二叉树中,如果所有分支结点都有左孩子和右孩子结点,并且叶子结点都集中在二叉树的最下层,这样的树叫做满二叉树
完全二叉树:
若二叉树中最多只有最下面两层的结点的度数可以小于2,并且最下面一层的叶子结点都是依次排列在该层最左边的位置上,则称为完全二叉树
区别:
满二叉树是完全二叉树的特例,因为满二叉树已经满了,而完全并不代表满。所以形态你也应该想象出来了吧,满指的是出了叶子节点外每个节点都有两个孩子,而完全的含义则是最后一层没有满。
二叉树的五个重要性质:
- 在二叉树的第i层上最多有2 i-1 个节点 。(i>=1)
- 二叉树中如果深度为k,那么最多有2k-1个节点。(k>=1)
- n0=n2+1 n0表示度数为0的节点 n2表示度数为2的节点
- 在完全二叉树中,具有n个节点的完全二叉树的深度为[log2n]+1,其中[log2n]+1是向下取整。
- 若对含 n 个结点的完全二叉树从上到下且从左至右进行 1 至 n 的编号,则对完全二叉树中任意一个编号为 i 的结点:
- 若 i=1,则该结点是二叉树的根,无双亲, 否则,编号为 [i/2] 的结点为其双亲结点;
- 若 2i>n,则该结点无左孩子, 否则,编号为 2i 的结点为其左孩子结点;
- 2i+1>n,则该结点无右孩子结点, 否则,编号为2i+1 的结点为其右孩子结点。
代码基本实现
实现中大量用了递归的方法,可以说递归思想是精髓。
#include <bits/stdc++.h>
using namespace std;
struct Node
{
int data;
Node *left = nullptr;
Node *right = nullptr;
};
//迭代方法实现建树,插入节点
void insertByIterate(Node *&root, int value) //注意root为Node*类型的引用,因为要对root本身进行修改
{
Node *node = new Node;
node->data = value;
if (root == nullptr)
{
root = node;
return;
}
else
{
Node *temp = root;
while (temp)
{
// if (value == temp->data) //避免插入重复元素
// return;
if (value < temp->data)
{
if (temp->left)
{
temp = temp->left;
}
else
{
temp->left = node;
return;
}
}
else
{
if (temp->right)
{
temp = temp->right;
}
else
{
temp->right = node;
return;
}
}
}
}
}
//递归方法实现实现建树,插入节点
// ! 可能无法记录父节点,自身层数
void insertByRecursion(Node *&root, int value)
{
if (root == nullptr)
{
root = new Node;
root->data = value;
return;
}
// if (data == root->data) //禁止重复元素
// return;
if (value < root->data)
insertByRecursion(root->left, value);
else
insertByRecursion(root->right, value);
}
void preorder(Node *root) //中序后序同理
{
if (root)
{
cout << root->data << ' ';
preorder(root->left);
preorder(root->right);
}
}
int main(void)
{
int arr[7] = {6, 1, 2, -10, 4, 5, 7};
Node *tree = nullptr;
for (size_t i = 0; i < 7; i++)
{
insertByRecursion(tree, arr[i]);
}
preorder(tree);
cout << endl;
return 0;
}
相关问题
L2-004 这是二叉搜索树吗?
一棵二叉搜索树可被递归地定义为具有下列性质的二叉树:对于任一结点,
- 其左子树中所有结点的键值小于该结点的键值;
- 其右子树中所有结点的键值大于等于该结点的键值;
- 其左右子树都是二叉搜索树。
所谓二叉搜索树的“镜像”,即将所有结点的左右子树对换位置后所得到的树。
给定一个整数键值序列,现请你编写程序,判断这是否是对一棵二叉搜索树或其镜像进行前序遍历的结果。
输入格式:
输入的第一行给出正整数 N(≤1000)。随后一行给出 N 个整数键值,其间以空格分隔。
输出格式:
如果输入序列是对一棵二叉搜索树或其镜像进行前序遍历的结果,则首先在一行中输出 YES
,然后在下一行输出该树后序遍历的结果。数字间有 1 个空格,一行的首尾不得有多余空格。若答案是否,则输出 NO
。
输入样例 1:
7
8 6 5 7 10 8 11
输出样例 1:
YES
5 7 6 8 11 10 8
输入样例 2:
7
8 10 11 8 6 7 5
输出样例 2:
YES
11 8 10 7 5 6 8
输入样例 3:
7
8 6 8 5 10 9 11
输出样例 3:
NO
思路
题解
#include <bits/stdc++.h>
using namespace std;
struct Node
{
int data;
Node *left = 0;
Node *right = 0;
} *tree = 0;
int n;
typedef vector<int> arr;
void insert(Node *&root, int value)
{
if (root == 0)
{
root = new Node;
root->data = value;
return;
}
if (value < root->data)
insert(root->left, value);
else
insert(root->right, value);
}
void preOrder(Node *root, vector<int> &res)
{
if (root)
{
res.push_back(root->data);
preOrder(root->left, res);
preOrder(root->right, res);
}
}
void preOrderMirror(Node *root, vector<int> &res)
{
if (root)
{
res.push_back(root->data);
preOrderMirror(root->right, res);
preOrderMirror(root->left, res);
}
}
void postOrder(Node *tree)
{
static int count(0);
if (tree)
{
postOrder(tree->left);
postOrder(tree->right);
cout << tree->data;
count++;
if (count != n)
cout << " ";
}
}
void postOrderMirror(Node *tree)
{
static int count(0);
if (tree)
{
postOrderMirror(tree->right);
postOrderMirror(tree->left);
cout << tree->data;
count++;
if (count != n)
cout << " ";
}
}
int main(void)
{
cin >> n;
vector<int> input;
int temp;
for (int i = 0; i < n; i++)
{
cin >> temp;
insert(tree, temp);
input.push_back(temp);
}
vector<int> res_pre, res_premirror;
preOrder(tree, res_pre);
preOrderMirror(tree, res_premirror);
if (input == res_pre)
{
cout << "YES" << endl;
postOrder(tree);
}
else if (input == res_premirror)
{
cout << "YES" << endl;
postOrderMirror(tree);
}
else
{
cout << "NO" << endl;
}
return 0;
}