课堂笔记:线性表的查找技术

顺序查找:普通的顺序查找方法、带监视哨的顺序查找方法
折半查找:折半查找的判定树

#include  
using namespace std; 
const int MaxSize = 100; 
class LineSearch{ 
public:     
	LineSearch(int a[], int n);
	~LineSearch() {}
	int SeqSearch(int k);
	int BinSearch1(int k);
	int BinSearch2(int low, int high, int k);
private:     
	int data[MaxSize];
	int length;
};
LineSearch :: LineSearch(int a[ ], int n){     
	for (int i = 0; i < n; i++)         
		data[i+1] = a[i];
	length = n; 
}

顺序查找 (线性查找)
基本思想: 从线性表的一端向另一端逐个将关键码与给定值进行比较, 若相等,则查找成功,给出该记录在表中的位置; 若整个表检测完仍未找到与给定值相等的关键码,则查找失败,给出失败信息。

int LineSearch :: SeqSearch(int k) 
{         
	i=n;      
	while (i>0 && data[i]!=k)          
		i--;      
	return i; 
}

改进的顺序查找
基本思想:设置“哨兵”。 哨兵就是待查值, 将哨兵放在查找方向的尽头处, 免去了在查找过程中每一次比较后都要判断查找位置是否越界,从而提高查找速度。

int LineSearch :: SeqSearch(int k) 
{      
	int i = length;
	data[0] = k;
	while (data[i] != k)
		i--;     
	return i;  
}

顺序查找查找性能的改进方法
记录每个数据的访问频率, 把访问频率高的数据移向顺序表的右端,可以减少查找成功时所进行的比较次数,提高效率
构造有序的顺序表,减少查找失败时所进行的比较次数,提高查找效率
单链表的顺序查找

int LinkSearch::SeqSearch2(Node *first, int k){    
	Node *p;  
	int count=0;
	p=first->next;   
	int j=1;
	while (p &&  p->data != k)  
	{
		p=p->next; 
		j++;    
		count++;
	}  
	if (!p){              
		cout<<"查找失败,比较的次数为:"<<count<<endl;                
		return 0;      
	} 
	else{      
		cout<<"\n"<<"查找成功,比较的次数为:"<<count<<endl;              
		return j;  
	} 
}

顺序查找的优点
算法简单而且使用面广。
对表中记录的存储结构没有任何要求,顺序存储和链接存储均可;
对表中记录的有序性也没有要求,无论记录是否按关键码有序均可。
顺序查找的缺点
平均查找长度较大,特别是当待查找集合中元素较多时,查找效率较低。
折半查找
适用条件
:线性表中的记录必须按关键码有序; 必须采用顺序存储。
基本思想
在有序表中(low, high,low<=high), 取中间记录作为比较对象, 若给定值与中间记录的关键码相等,则查找成功; 若给定值小于中间记录的关键码,则在中间记录的左半区继续查找; 若给定值大于中间记录的关键码,则在中间记录的右半区继续查找。 不断重复上述过程,直到查找成功,或所查找的区域无记录,查找失败。

int LineSearch :: BinSearch1(int k){      
	int mid, low = 1, high = length;
	while (low <= high) {
		mid = (low + high) / 2;            
		if (k < data[mid])                
			high = mid - 1;
		else if (k > data[mid])                 
			low = mid + 1;            
		else                
			return mid;
	}       
	return 0;
}
int LineSearch :: BinSearch2(int low, int high, int k){       
	if (low > high)            
		return 0;
	else {          
		int mid = (low + high) / 2;
		if (k < data[mid])             
			return BinSearch2(low, mid-1, k);       
		else if (k > data[mid])             
			return BinSearch2(mid+1, high, k);        
		else             
			return mid;
	} 
}

折半查找判定树
判定树:折半查找的过程可以用二叉树来描述, 树中的每个结点对应有序表中的一个记录, 结点的值为该记录在表中的位置。 通常称这个描述折半查找过程的二叉树为折半查找判定树,简称判定树。
判定树的构造方法
⑴ 当n=0时,折半查找判定树为空;
⑵ 当n>0时,折半查找判定树的根结点为mid=(n+1)/2,根结点的左子树是与有序表r[1] ~ r[mid-1]相对应的折半查找判定树,根结点的右子树是与r[mid+1] ~ r[n]相对应的折半查找判定树。
判定树的特点
任意两棵折半查找判定树,若它们的结点个数相同,则它们的结构完全相同
具有n个结点的折半查找树的高度为(log2n向下取整+1)。
判定树的性质
任意结点的左右子树中结点个数最多相差1
任意结点的左右子树的高度最多相差1
任意两个叶子所处的层次最多相差1
折半查找性能分析
查找成功:在表中查找任一记录的过程,即是折半查找判定树中从根结点到该记录结点的路径,和给定值的比较次数等于该记录结点在树中的层数。
查找不成功:查找失败的过程就是走了一条从根结点到外部结点的路径, 和给定值进行的关键码的比较次数等于该路径上内部结点的个数(失败情况下的平均查找长度等于树的高度)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值