线性表上的查找
- 顺序查找
. 折半查找
. 分块查找
分块查找
- 将表分成若干块
- 块间有序,块内无序(或者有序)
树表的查找
- 表结构在查找过程中动态生成
- 二叉排序树, 平衡二叉树 , B- 树, B+ 树,键树
二叉排序树
- 若左子树非空, 则左子树所有结点的值均小于根结点的值
- 若右子树非空,则右子树所有结点的值均大于根结点的值
- 左右子树本身又是一棵二叉排序树
二叉排序的查找
- key > 结点值,查右子树
- key > 结点值,查左子树
Tree Search(Tree t , int v){
//if (t == NULL) return 0;
if (!t ||t->data == v) return t;
else if (t->data > v) return Search(t->lchild , v);
else if (t->data < v) return Search(t->rchild , v);
}
二叉排序的插入
- 若二叉排序树为空,则插入结点作为根结点插入到空树中
- 否则在左右子树上查找
- 树中已经有,不再插入
- 没有这个元素
- 查找直到某个叶子结点的左子树或者右子树为空为止
- 结点为叶子结点的左孩子或者右孩子
void insertTree(Tree *t , int v){
if (*t == NULL){
*t = (Tree)malloc(sizeof(TreeNode));
(*t)->data = v;
(*t)->lchild = NULL;
(*t)->rchild = NULL;
return ;
}
if ((*t)->data == v) return ;
if (v < (*t)->data)insertTree(&((*t)->lchild) , v);
else if (v > (*t)->data) insertTree(&((*t)->rchild) , v);
}
二叉排序的生成
void initTree (Tree *t , int *a , int length){
int i;
for (i = 0 ; i < length ; i ++){
insertTree(t , a[i]);
}
}
二叉排序的删除
- 删除叶子结点,直接删除该结点,其对应双亲的孩子域改为空
- 删除的结点只有左子树或者右子树,用左子树或者右子树代替它
- 既有左子树又有右子树
- 用中序排列的前驱结点代替
- 用中序排列的后驱结点来代替
void deleteNode (Tree *t , int v){
Tree p = *t , pre = NULL , temp = NULL , s = NULL;
//查找双亲结点以及想要查找的结点
while (p){
if (p->data == v) break;
pre = p;
if (v < p->data) p = p->lchild;
else if (v > p->data) p = p->rchild;
}
if (!p) return;
//删除结点
if (p->lchild == NULL){
temp = p;
p = p->rchild;
//free(temp);
}
else if (p->rchild == NULL){
temp = p;
p = p->lchild;
//free(temp);
}
else if (p->lchild && p->rchild){
temp = p;
s = p->lchild;
while (s->rchild){
temp = s;
s = s->rchild;
}
p->data = s->data;
//将前驱结点的父节点右子树改为前驱结点的左子树
if (temp != p) temp->rchild = s->lchild;
else p->lchild = s->lchild;
free(temp);
return ;
}
if (!pre) *t = pre;
else if (temp == pre->lchild) pre->lchild = p;
else pre->rchild = p;
free(temp);
}
== pre->lchild) pre->lchild = p;
else pre->rchild = p;
free(temp);
}