BST
概念
二叉排序树需要满足以下性质:
①
①
①若根结点的左子树非空,则左子树中所有的结点的值都小于等于根结点的值;
②
②
②若根结点的右子树非空,与左子树非空时相反;
③
③
③其左右子树皆为二叉排序树。
当然也可以为空,一棵空树也是一棵二叉排序树。
实现
- 插入
以结构体存储树
struct TreeNote {
int l, r, data;
};
TreeNote tree[N];
采用递归的方法构造二叉树
void insert(int pos, int data) {
if (tree[pos].data == 0) {
tree[pos].data=data;
return;
}
else if (tree[pos].data > data) {
tree[pos].l=2 * pos;
insert(tree[pos].l,data);
}
else {
tree[pos].r=2 * pos + 1;
insert(tree[pos].r,data);
}
}
时间复杂度经验证一般为
O
(
log
2
n
)
O(\log_2n)
O(log2n),
当树退化为一条链时,时间复杂度为
O
(
n
)
O(n)
O(n)。
除了上面的,还有一种实现方式:
void insert(int pos, int data) {
if (data<tree[pos].data) {
if (tree[pos].l == 0) {
tree[pos].l=2 * pos;
tree[tree[pos].l].data=data;
return;
}
else {
insert(tree[pos].l,data);
}
}
else {
if (tree[pos].r == 0) {
tree[pos].r=2 * pos + 1;
tree[tree[pos].r].data=data;
return;
}
else {
insert(tree[pos].r,data);
}
}
}
两种方式的区别在于对象不同
第一种实现方式的思想是寻找一个空结点将数据插入;
第二种则是寻找当前结点的空儿子结点,插入数据。
说白了区别就是找空根结点还是找空的儿子结点。
调用都为:
buildTree(1,data)
data为需插入的数据。
- 查询
对构造好的二叉排序树中序遍历。
int inorder(int pos) {
if (tree[pos].data != 0) {
inorder(tree[pos].l);
//printf("%d\n",tree[pos].data);
inorder(tree[pos].r);
}
return 0;
}
后记
这算法我用起来好像特玄学,果然安安静静打快排最踏实。
,可能是我太弱了 (大雾 。