查找技术
Posted 钟钟终
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了查找技术相关的知识,希望对你有一定的参考价值。
查找的基本概念
关键码:可以表示一个记录的某个数据项;若能唯一标识,称为主关键码,否则为次关键码。
查找:在具有相同类型的记录构成的集合中找出给定条件的记录。
静态查找和动态查找的区别:是否涉及到插入和删除操作。
查找算法的性能:通过平均查找长度ASL进行衡量。
查找结构有:
1.线性表
顺序查找、折半查找、折半查找的递归算法实现,通过插入排序使得数组有序(设置哨兵)
对于表中每个记录的查找过程,可以用折半查找的判定树来描述:
1.从根节点到该节点的路径、给定值的比较次数都等于该记录节点在树中的层数。
2.比较次数最多为log2(n)+1
#include <bits/stdc++.h>
using namespace std;
const int N=1e4+5;
int a[N];
class Lin_search
public:
Lin_search(int a[],int n); //线性表的初始化
~Lin_search() //静态数组,析构函数可为空
int Seq_search(int k); //顺序查找
void Insert_sort();
int Bin_search1(int k); //折半查找
int Bin_search2(int l,int r,int k); //折半的递归写法
void display()
for(int i=1;i<=length;i++)
cout<<d[i]<<" ";
cout<<endl;
private:
int d[N];
int length;
;
Lin_search::Lin_search(int a[],int n)
for(int i=1;i<=n;i++) //添加哨兵写法
d[i]=a[i];
length=n;
int Lin_search::Seq_search(int k)
int i=length;
d[0]=d[i]; //哨兵,不必判断是否越界
while(d[i]!=k)
i--;
return i;
void Lin_search::Insert_sort()
for(int i=2;i<=length;i++)
d[0]=d[i]; //设置哨兵
int j;
for(j=i-1;d[j]>d[0];j--)
d[j+1]=d[j];
d[j+1]=d[0];
int Lin_search::Bin_search1(int k)
int mid,l=1,r=length;
while(l<r)
mid=l+r>>1;
if(k<d[mid])
r=mid-1;
else if(k>d[mid])
l=mid+1;
else
return mid;
int Lin_search::Bin_search2(int l,int r,int k)
if(l>r)
return 0;
else
int mid=(l+r)/2;
if(d[mid]>k)
return Bin_search2(l,mid-1,k);
else if(d[mid]<k)
return Bin_search2(mid+1,r,k);
else
return mid;
int main()
/*
测试数据
5
5 4 6 10 8
*/
int n;cin>>n;
for(int i=1;i<=n;i++)
cin>>a[i];
Lin_search lin=Lin_search(a,n);
cout<<"顺序查找给定值10,在线性表中下标:"<<lin.Seq_search(10)<<endl;
printf("折半查找要求有序表按关键字升序排列,因此我们使用第八章插入排序对表进行排列!\\n");
lin.Insert_sort();
lin.display();
cout<<"折半查找给定值10,在线性表中下标:"<<lin.Bin_search1(10)<<endl;
cout<<"折半查找(递归形式)给定值10,在线性表中下标:"<<lin.Bin_search2(1,n,10)<<endl;
return 0;
树表的查找技术
二叉排序树:
1.左右子树都是二叉排序树
2.若左子树不空,则左子树上所有节点的值均小于根节点的值
3.若右子树不空,则右子树上所有节点的值均大于根节点的值
将具体实现的实现方法放到私有成员中的原因:如果从外界访问,是无法指定从根节点开始遍历的,而类内部可以直接使用。
指针指向的地址,重点理解返回指针类型的方法。
二叉树的删除暂时跳过
#include<bits/stdc++.h>
using namespace std;
const int N=1e4+5;
struct Binode
int data;
Binode* lc,* rc;
;
class Binode_sort
public:
Binode_sort(int a[],int n);
~Binode_sort() Release(root);
Binode* insert_bst(int x)
return insert_bst(root,x);
void preorder()
preorder(root);
Binode* search_bst(int x)
search_bst(root,x);
private:
Binode* insert_bst(Binode* bt,int x);
Binode* search_bst(Binode* bt,int x);
Binode* root;
void Release(Binode* bt);
void preorder(Binode* bt); //中序遍历,前序和后序同理
;
Binode_sort::Binode_sort(int a[],int n)
root=NULL;
for(int i=1;i<=n;i++)
root=insert_bst(root,a[i]); //关键出错点 服了
void Binode_sort::Release(Binode* bt)
if(bt==NULL)
return;
else
Release(bt->lc);
Release(bt->rc);
delete bt;
Binode* Binode_sort::insert_bst(Binode* bt,int x)
if(bt==NULL)
Binode* s=new Binode;
s->data=x;
s->lc=s->rc=NULL;
bt=s;
return bt;
else if (bt->data > x)
bt->lc=insert_bst(bt->lc, x);
else
bt->rc = insert_bst(bt->rc, x);
Binode* Binode_sort::search_bst(Binode* bt,int x)
if(bt==NULL) return NULL;
if(bt->data==x)
return bt;
else if(bt->data>x)
return search_bst(bt->lc,x);
else
return search_bst(bt->rc,x);
void Binode_sort::preorder(Binode* bt)
if(bt==NULL)
return;
else
preorder(bt->lc);
cout<<bt->data<<" ";
preorder(bt->rc);
int main()
/* 测试样例
5
4 5 3 1 10
*/
int n,a[N];cin>>n;
for(int i=1;i<=n;i++)
cin>>a[i];
Binode_sort bst=Binode_sort(a,n);
bst.preorder();
printf("\\n");
Binode* p=bst.search_bst(5);
cout<<"查找给定值的地址:"<<p<<"\\t左子树根节点地址:"<<p->rc<<"\\t右子树根节点:"<<p->rc<<endl;
return 0;
基于散列表的查找技术
散列表:一块连续的存储空间
散列(哈希)函数:将关键码映射为散列表中适当存储位置的函数
冲突:两个不同的记录放到同一个位置
同义词:造成冲突的两个数
开放地址法:
#include <bits/stdc++.h>
using namespace std;
const int N=1e4+4;
class Hash1
public:
Hash1();
~Hash1()
int ins(int k);
int del(int k);
int sear(int k);
private:
int H(int k);
int ht[N];
;
Hash1::Hash1() //初始化 清0
memset(ht,0,sizeof(ht));
int Hash1::H(int k) //散列函数
return k%11;
int Hash1::ins(int k) //插入给定值
int g=H(k);
if(ht[g]!=0)
while(ht[g]!=0)
g=(g+1)%N;
ht[g]=k;
else
ht[g]=k;
int Hash1::sear(int k) //检索给定值在表中位置
int i,j=H(k);
i=j;
while(ht[i]!=0)
if(ht[i]==k) return i;
else i=(i+1)%N;
return -1;
int Hash1::del(int k)
int g=H(k);
while(ht[g]!=0)
if(ht[g]==k)
return g;
else g=(g+1)%N;
return -1;
int main()
Hash1 h1=Hash1() ;
h1.ins(2);
h1.ins(13);
h1.ins(25);
cout<<h1.sear(13)<<endl;
cout<<h1.sear(25)<<endl;
int tmp=h1.del(25);
if(tmp!=-1)
printf("删除成功!在下标%d处。",tmp);
else
printf("表中不出在该值。");
return 0;
拉链法
#include<bits/stdc++.h>
using namespace std;
const int N=1e4+5;
struct Node
int data;
Node* nxt;
;
class Hash2
public:
Hash2();
~Hash2();
int ins(int k);
int del(int k);
Node* sear(int k);
private:
int H(int k);
Node* ht[N];
;
Hash2::Hash2()
for(int i=0;i<N;i++)
ht[i]=new Node; //为node申请空间,书中没写!!
ht[i]->nxt=NULL;
Hash2::~Hash2()
Node* p=NULL,* q=NULL;
for(int i=0;i<N;i++)
p=q=ht[i];
while(p!=NULL)
p=p->nxt;
delete q;
q=p;
int Hash2::H(int k)
return k%11;
int Hash2::ins(int k)
Node* p=ht[H(k)],* s=NULL;
s=new Node;
s->data=k;
s->nxt=p->nxt;
p->nxt=s;
return 1;
Node* Hash2::sear(int k)
Node* p=ht[H(k)];
while(p!=NULL)
if(p->data==k)
return p;
p=p->nxt;
return NULL;
int Hash2::del(int k)
Node* p=ht[H(k)],* q=NULL;
while(p!=NULL)
q=p->nxt;
if(q->data==k)
p->nxt=q->nxt;
delete q;
return 1;
p=p->nxt;
return -1;
int main()
Hash2 h1=Hash2();
h1.ins(2);
h1.ins(13);
h1.ins(24);
if(h1.sear(13))
cout<<"查找成功!存储值:"<<h1.sear(13)->data<<endl;
if(h1.del(以上是关于查找技术的主要内容,如果未能解决你的问题,请参考以下文章