#二叉查找树
##insert
(sp:重复元的插入可以通过在节点记录中保留一个附加域用来指示频率)
searchtree insert(elementtype x,searchtree t) {
if (t == NULL) {
t = malloc(sizeof(struct treenode));
if (t == NULL)
fataerror("out of space");
else
{
t->element = x;
t->left = t->right = NULL;
}}
else if (x > t->element)
t->right = insert(x, t->right);
else if (x < t->element)
t->left = insert(x, t->left);return t;
}
##delete
删除操作不多时,可使用懒惰删除,当一个元素被删除时只做一个删除记号(尤其在有重复关键字时)
searchtree delete(elementtype x, searchtree T)
{
position tmp;if (t == NULL)
error("element not found");else
if (x < t->element)
t->left = delete(x, t->left);else
if (x > t->element)
t->right = delete(x, t->right);
//two son
else if (t->left && t->right) {
tmp = findmin(t->right);
t->element = tmp->element;
t->right = delete(t->element, t->right);
}//one or two son
else {
tmp = t;
if (t->left == NULL)
t = t->right;
else if (t->right == NULL)
t = t->left;free tmp;
}return t;
}
##AVL树
(带有平衡条件)每个节点的左子树和右子树的高度最多差1的二叉查找树
###单旋转
不平衡情况
1.对a的左儿子(右儿子)的左子树(右子树)进行插入
//root——k2,left——k1
position singleleft(position k2)
{
position = k2->left;
k2->left = position->right;
position->right = k2;
return k1;
}
###双旋转
2.对a的左儿子(右儿子)的右子树(左子树)进行插入
先对左儿子进行一次旋转变为1情况,在对root 进行一次单旋转、
position doubleleft(position k3)
{
k3->left=singleright(k3->left);
return singleleft(k3);
}
avltree insert(elementtype x, avltree t)
{
if (t == NULL) {
t = malloc(sizeof(struct avlnode));
if (t == NULL)
fataerror("out of space ");
}else if (x > t->element) {
t->right = insert(x, t-> right);
if (height(t->right) - height(t->left) >= 2) {
if (x > t->right->element)t = singleright(t);else (x < t->right->element) t = doubleright(t);
}
}//同上
}
##伸展树
当一个节点被访问后,它就要经过一系列旋转被放到根上(不要求保持平衡)