静态查找:数据集合稳定,不需要添加和删除元素的查找操作。(线性表、折半)
动态查找:数据集合在查找的过程中需要同时添加或删除元素的查找操作。(二叉排序、散列表)
(1)顺序查找:从第一个(或者最后一个)记录开始,逐个进行记录的关键字和给定值进行比较,若某个记录的关键字和给定值相等,则查找成功。如果查找所有记录找不到与给定值相等的关键字,则查找不成功。
int Sq_Search(int *a, int n, int key)
{
int i = n;
a[0] = key
while( a[i] != key ) i--;
return i;
}
(2)插值查找(按比例查找)
int bin_search( int str[], int n, int key )
{
int low, high, mid;
low = 0;
high = n-1;
while( low <= high )
{
mid = low + (key-a[low]/a[high]-a[low])*(high-low); // 插值查找的唯一不同点
if( str[mid] == key ) return mid;
if( str[mid] < key ) low = mid + 1;
if( str[mid] > key ) high = mid - 1;
}
return -1;
}
(3)斐波那契查找(黄金比例查找法)
#define MAXSIZE 20
void fibonacci(int *f)
{
int i;
f[0] = 1;
f[1] = 1;
for(i=2; i < MAXSIZE; ++i) f[i] = f[i-2] + f[i-1];
}
int fibonacci_search(int *a,int key,int n)
{
int low = 0;
int high = n - 1;
int mid = 0;
int k = 0;
int F[MAXSIZE];
int i;
fibonacci(F);
while( n > F[k]-1 ) ++k;
for( i=n; i < F[k]-1; ++i) a[i] = a[high];
while( low <= high )
{
mid = low + F[k-1] - 1;
if( a[mid] > key )
{
high = mid - 1;
k = k - 1;
}
else if( a[mid] < key )
{
low = mid + 1;
k = k - 2;
}
else
{
if( mid <= high ) return mid;
else return high;
}
}
return -1;
}
(4)二叉排序树
二叉排序数又称为二叉查找树,它或者是一棵空树,或者具有下列性质的二叉树:若它的左子树不为空,则左子树上所有结点的值均小于它的根结构的值;若它的右子树不为空,则右子树上所有结点的值均大于它的根结构的值;它的左右子树也分别为二叉排序树(递归)
// 二叉树的二叉链表结点结构定义
typedef struct BiTNode
{
int data;
struct BiTNode *lchild, *rchild;
}BiTNode, *BiTree;
// 递归查找二叉排序树 T 中是否存在 key
// 指针 f 指向 T 的双亲,其初始值调用值为 NULL
// 若查找成功,则指针 p 指向该数据元素结点,并返回 TRUE
// 否则指针 p 指向查找路径上访问的最后一个结点,并返回 FALSE
Status SearchBST(BiTree T, int key, BiTree f, BiTree *p)
{
if( !T ) // 查找不成功
{
*p = f;
return FALSE;
}
else if( key == T->data ) // 查找成功
{
*p = T;
return TRUE;
}
else if( key < T->data )
{
return SearchBST( T->lchild, key, T, p ); // 在左子树继续查找
}
else
{
return SearchBST( T->rchild, key, T, p ); // 在右子树继续查找
}
}
// 当二叉排序树 T 中不存在关键字等于 key 的数据元素时,
// 插入 key 并返回 TRUE,否则返回 FALSE
Status InsertBST(BiTree *T, int key)
{
BiTree p, s;
if( !SearchBST(*T, key, NULL, &p) )
{
s = (BiTree)malloc(sizeof(BiTNode));
s->data = key;
s->lchild = s->rchild = NULL;
if( !p )
{
*T = s; // 插入 s 为新的根结点
}
else if( key < p->data )
{
p->lchild = s; // 插入 s 为左孩子
}
else
{
p->rchild = s; // 插入 s 为右孩子
}
return TRUE;
}
else
{
return FALSE; // 树中已有关键字相同的结点,不再插入
}
}
删除操作:
Status DeleteBST(BiTree *T, int key)
{
if( !*T ) return FALSE;
else
{
if( key == (*T)->data ) return Delete(T);
else if( key < (*T)->data ) return DeleteBST(&(*T)->lchild, key);
else return DeleteBST(&(*T)->rchild, key);
}
}
Status Delete(BiTree *p)
{
BiTree q, s;
if( (*p)->rchild == NULL )
{
q = *p;
*p = (*p)->lchild;
free(q);
}
else if( (*p)->lchild == NULL )
{
q = *p;
*p = (*p)->rchild;
free(q);
}
else
{
q = *p;
s = (*p)->lchild;
while( s->rchild )
{
q = s;
s = s->rchild;
}
(*p)->data = s->data;
if( q != *p )
{
q->rchild = s->lchild;
}
else
{
q->lchild = s->lchild;
}
free(s);
}
return TRUE;
}
(5)红黑树
红黑树是一种平衡的二叉查找树。出了符合二叉查找树的特性之外,还具有下列的特性:
节点是红色或者黑色;根节点是黑色;每个叶子的节点都是黑色的空节点(NULL);每个红色节点的两个子节点都是黑色的;从任意节点到其每个叶子的所有路径都包含相同的黑色节点