静态查找:数据集合稳定,不需要添加,删除元素的查找操作。
动态查找:数据集合在查找的过程中需要同时添加或删除元素的查找操作。
查找结构
对于静态查找来说,我们不妨可以用线性表结构组织数据,这样可以使用顺序查找算法,如果我们再对关键字进行排序,则可以使用折半查找算法或斐波那契查找算法等来提高查找的效率。
对于动态查找来说,我们则可以考虑使用二叉排序树的查找技术,另外我们还可以使用散列表结构来解决一些查找问题
顺序查找又叫线性查找,是最基本的查找技术,它的查找过程是:从第一个(或者最后一个)记录开始,逐个进行记录的关键字和给定值进行比较,若某个记录的关键字和给定值相等,则查找成功。如果查找了所有的记录仍然找不到与给定值相等的关键字,则查找不成功。
查找表:是由同一种类型的数据元素构成的集合。查找表中的数据元素是完全松散的,数据元素之间没有直接的联系
静态查找
#include<stdio.h>
#include<string.h>
#include<malloc.h>
#include<stdlib.h>
#define INFINITY 65535 //定义一个无限大的值
#define MaxSize 50 //最大顶点个数
#include <iostream>
using namespace std;
typedef char VertexType[4];
typedef char InfoPtr;
typedef int VRType;
typedef struct{
KeyType key;
}DataType;
typedef struct{
DataType list[MaxSize];
int length;
}SSTable;
//顺序表的查找算法 O(n)
int SeqSearch(SSTable S,DataType x){
int i=0;
while(i<S.length&&S.list[i].key!=x.key){
i++;
}
if(S.list[i].key==x.key){
return i+1;
}else{
return 0;
}
}
//设置监视哨 监视哨可以防止出现数组越界。
int SeqSearch2(SSTable S,DataType x){
int i=S.length;
S.list[0].key=x.key;
while(S.list[i].key!=x.key){
i--;
}
return i;
}
//有序顺序表 顺序查找和折半查找
//顺序查找
//设置监视哨 监视哨可以防止出现数组越界。
int SeqSearch2(SSTable S,DataType x){
int i=S.length;
S.list[0].key=x.key;
while(S.list[i].key!=x.key){
i--;
}
return i;
}
//折半查找(插值查找,二分查找) 前提条件是表中的数据元素有序排列。所谓折半查找就是
//在所要查找元素集合的范围内,依次与表中间位置的元素进行查找,如果找到
//与关键字相等的元素,则说明查找成功,否则利用中间位置将表分成两端。
int BinarySearch(SSTable S,DataType x){
int low,high,mid;
low=0;high=S.length-1;
while(low<=high){
mid=(low+high)/2;
if(S.list[mid].key==x.key){
return mid+1;
}else if(S.list[mid].key<x.key){
low=mid+1;
}else if(S.list[mid].key>x.key){
high=mid-1;
}
}
return 0;
}
动态查找
#include<stdio.h>
#include<string.h>
#include<malloc.h>
#include<stdlib.h>
#define INFINITY 65535 //定义一个无限大的值
#define MaxSize 50 //最大顶点个数
#include <iostream>
using namespace std;
typedef char VertexType[4];
typedef char InfoPtr;
typedef int VRType;
typedef struct{
int key;
}DataType;
typedef struct Node{
DataType data;
struct Node *lchild,*rchild;
}BiTreeNode,*BiTree;
void DeleteNode(BiTree *s);
void InOrderTrave(BiTree T);
BiTree BSTSearch(BiTree T,DataType x);
int BSTInsert(BiTree *T,DataType x);
int BSTDelete(BiTree *T,DataType x);
//二叉排序树的查找算法
BiTree BSTSearch(BiTree T,DataType x){
BiTreeNode *p;
if(T!=NULL){
p=T;
while(p!=NULL){
if(p->data.key==x.key)
return p;
else if(x.key<p->data.key)
p=p->lchild;
else
p=p->rchild;
}
}
return NULL;
}
//二叉排序树的插入操作
int BSTInsert(BiTree *T,DataType x){
BiTreeNode *p,*cur,*parent=NULL;
cur=*T;
while(cur!=NULL){
if(cur->data.key==x.key)
return 0;
parent=cur;
if(x.key<cur->data.key){
cur=cur->lchild;
}else{
cur=cur->rchild;
}
}
p=(BiTreeNode*)malloc(sizeof(BiTreeNode));
if(!p)
exit(-1);
p->data=x;
p->lchild=NULL;
p->rchild=NULL;
if(!parent)
*T=p;
else if(x.key<parent->data.key){
parent->lchild=p;
} else{
parent->rchild=p;
}
return 1;
}
//二叉排序树的删除
int BSTDelete(BiTree *T,DataType x){
if(!T){
return 0;
}else{
if(x.key==(*T)->data.key)
DeleteNode(T);
else if((*T)->data.key>x.key ){
BSTDelete(&(*T)->lchild,x);
}else{
BSTDelete(&(*T)->rchild,x);
}
return 1;
}
}
void DeleteNode(BiTree *s){
BiTree q,x,y;
if(!(*s)->lchild){
q=*s;
*s=(*s)->lchild;
free(q);
}else if(!(*s)->rchild){
q=*s;
*s=(*s)->rchild;
free(q);
}else{
x=*s;
y=(*s)->lchild;
while(y->rchild){
x=y;
y=y->rchild;
}
(*s)->data=y->data;
if(x!=*s){
x->rchild=y->lchild;
}else{
x->lchild=y->rchild;
}
free(y);
}
}
//中序遍历二叉排序树的递归实现
void InOrderTrave(BiTree T){
if(T){
InOrderTrave(T->lchild);
printf("%4d",T->data);
InOrderTrave(T->rchild);
}
}
//二叉排序树
int main(){
BiTree T=NULL,p;
DataType table[]={37,32,35,62,82,95,13,5,73};
int n=sizeof(table)/sizeof(table[0]);
DataType x={73},s={32};
int i;
for(i=0;i<n;i++){
BSTInsert(&T,table[i]);
}
printf("中序遍历二叉排序树得到的序列为:\n");
InOrderTrave(T);
p=BSTSearch(T,x);
if(p!=NULL){
printf("\n二叉排序树查找,关键字%d存在\n",x.key);
}else{
printf("查找失败");
}
BSTDelete(&T,s);
printf("删除元素%d后,中序遍历二叉排序树得到的序列为:\n",s.key);
InOrderTrave(T);
return 1;
}