查找技术可从以下几个方面去讨论:
第一: 线性表的查找技术
第二:树表的查找技术
第三:散列表的查找技术
下面来讨论第一个:线性表的查找技术
1 顺序查找
1.1顺序表的顺序查找
基本思想:从线性表的一端向另一端逐个将关键码与给定值进行比较,若相等,则查找成功,给出该记录在表中的位置;若扫描完整个表都未找到,则失败,并给出信息
图片:
算法实现:
int SeqSearch1(int r[], int n, int k){
r[0]=k ; //设置哨兵
int i=n;
while (r[i]!=k) //若r[i]与k相等,则返回当前i的值;否则继续比较前一个记录;
i--;
return i;
}
1.2单链表的顺序查找
代码实现:
//LinkSearch.h
#ifndef LinkSEARCH_H
#define LinkSEARCH_H
struct Node
{
int data;
Node *next;
};
class LinkSearch
{
public:
LinkList(int a[ ], int n); //建立有n个元素的单链表
void PrintList( ); //遍历单链表,按序号依次输出各元素
int SeqSearch2(Node *first, int k);//查找单链表中是否存在元素k
Node *GetFirst( );
private:
Node *first; //单链表的头指针
};
#endif
//LinkSearch.cpp
#include "LinkSearch.h"
#include <iostream>
using namespace std;
/*
* 前置条件:单链表不存在
* 输 入:顺序表信息的数组形式a[],单链表长度n
* 功 能:将数组a[]中元素建为长度为n的单链表
* 输 出:无
* 后置条件:构建一个单链表
*/
LinkSearch::LinkList(int a[],int n)
{
first=new Node; //生成头结点
Node *r,*s;
r=first; //尾指针初始化
for (int i=0; i<n; i++)
{
s=new Node; s->data=a[i]; //为每个数组元素建立一个结点
r->next=s; r=s; //插入到终端结点之后
}
r->next=NULL; //单链表建立完毕,将终端结点的指针域置空
}
/*
* 前置条件:单链表存在
* 输 入:无
* 功 能:单链表遍历
* 输 出:输出所有元素
* 后置条件:单链表不变
*/
void LinkSearch::PrintList( )
{
Node *p;
p=first->next;
cout<<"单链表中的元素为:"<<endl;
while (p)
{
cout<<p->data<<" ";
p=p->next;
}
}
/*
* 单链表的顺序查找
*/
int LinkSearch::SeqSearch2(Node *first, int k)
{
Node *p;
int count=0;
p=first->next;
int j=1;
while ( p->data != k)
{
p=p->next;
j++;count++;
}
if (p->data==k){
cout<<"\n"<<"比较的次数为:"<<count<<endl;
return j;
}
else{
cout<<"比较的次数为:"<<count<<endl;
return 0;
}
}
/*
* 取头节点
*/
Node* LinkSearch::GetFirst()
{
return first;
}
2 拆半查找
前提要求: 所有记录必须按关键码有序,并且采取用顺序存储。
伪代码描述:
1. 设置初始查找区间;
low=1;high=n;
2. 测试查找区间[low,high]是否存在,若不存在,则查找失败;否则
3. 取中间点mid=(low+high)/2;比较k与r[mid],有以下三种情况:
3.1 若k<r[mid],high=mid-1;查找在左半区进行,转2;
3.2 若k>r[mid],low=mid+1;查找在右半区进行,转2;
3.3 若k=r[mid],查找成功,返回记录在表中位置mid;
图解:
算法实现:
(1)非递归实现
int BinSearch1(int r[ ], int n, int k)
{
int low=0, high=n; //设置初始查找区间
while (low<=high)
{
int mid=(low+high)/2; //取中间点, 比较k与r[mid],
if (k<r[mid])
high=mid-1;
else
if (k>r[mid])
low=mid+1;
else
return mid; //查找成功
}
return 0; //查找失败
}
(2)递归实现
int BinSearch2(int r[], int low, int high, int k)
{
if (low>high)
return 0; //递归的边界条件
else
{
int mid=(low+high)/2;
if (k<r[mid])
return BinSearch2(r, low, mid-1, k); //查找在左半区进行
else
if (k>r[mid])
return BinSearch2(r, mid+1, high, k); //查找在右半区进行
else
return mid;
}
}