ListSet_对半搜索的递归算法

对半搜索是一种二分搜索, 将表划分为长度几乎相等的两个子表.

共有函数Search()调用私有函数BSearch(). 而后递归调用BSearch()函数实现对有序表的对半搜索.

mid, left, right均为元素下标, 如果当前表不为空, 则令x与l[mid]比较. 若两者相等, 则搜索成功. 若前者小于后者, 则继续查找左半部分, 否

则查找右半部分. 下标范围分别为[left, mid - 1], [mid + 1, right]. 如果当前搜索表为空表, 搜索失败返回NotPresent.

实现代码:

#include "iostream"
#include "cstdio"
#include "cstring"
#include "algorithm"
#include "assert.h"
using namespace std;
const int MAXN = 9999;

enum ResultCode
{
    Underflow, Overflow, Success, Duplicate, NotPresent
};
template <class T>
class DynamicSet
{
public:
	virtual ResultCode Search(T &x) const = 0; // 表中搜索与x关键字相同的元素, 若存在则赋值给x并且返回Success, 否则返回NotPresent
	virtual ResultCode Insert(T &x) = 0; // 表中搜索与x关键字相同的元素, 若存在该元素, 赋值给x返回Duplicate, 若表已满返回Overflow, 若表未满返回Success
	virtual ResultCode Remove(T &x) = 0; // 表中搜索与x关键字相同的元素, 若存在该元素, 赋值给x返回Success, 否则返回NotPresent
	virtual bool IsEmpty() const = 0; // 集合为空返回true
	virtual bool IsFull() const = 0; // 集合为满返回true
	/* data */
};

template <class T>
class ListSet: public DynamicSet<T>
{
public:
	ListSet( int mSize );
	~ListSet() { delete []l; }
	bool IsEmpty() const { return n == 0; }
	bool IsFull() const { return n == maxSize; }
	ResultCode Search(T &x) const;
	ResultCode Insert(T &x);
	ResultCode Remove(T &x);
	void Print();
private:
	T *l;
	int maxSize, n;
	int BSearch(T &x, int left, int right) const;
	/* data */
};

template <class T>
void ListSet<T>::Print()
{
	for(int i = 0; i < n; ++i)
		cout << l[i] << "\t";
	cout << endl;
}

template <class T>
ListSet<T>::ListSet(int mSize)
{
	maxSize = mSize;
	l = new T[maxSize];
	n = 0;
}

template <class T>
ResultCode ListSet<T>::Insert(T &x)
{
	assert(!IsFull());
	l[n++] = x;
	l[n] = MAXN;
	return Success;
}

template <class T>
ResultCode ListSet<T>::Remove(T &x)
{

}

template <class T>
ResultCode ListSet<T>::Search(T &x) const
{
	int i = BSearch(x, 0, n - 1);
	if(i == -1) return NotPresent;
	x = l[i];
	return Success;
}

template <class T>
int ListSet<T>::BSearch(T &x, int left, int right) const
{
	if(left <= right) {
		int mid = (left + right) / 2;
		if(x < l[mid]) return BSearch(x, left, mid - 1);
		else if(x > l[mid]) return BSearch(x, mid + 1, right);
		else return mid;
	}
	return -1;
}

int main(int argc, char const *argv[])
{
	ListSet<int> ls(20);
	int x = 21; ls.Insert(x);
	x = 30; ls.Insert(x);
 	x = 36; ls.Insert(x);
	x = 41; ls.Insert(x);
 	x = 52; ls.Insert(x);
	x = 54; ls.Insert(x);
	x = 66; ls.Insert(x);
	x = 72; ls.Insert(x);
	x = 83; ls.Insert(x);
	x = 97; ls.Insert(x);
	ls.Print();
	x = 66;
	if(ls.Search(x) == Success) cout << "Found " << x << endl;
	else cout << "Not Found " << x << endl;
	return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-17 07:44:15

ListSet_对半搜索的递归算法的相关文章

ListSet_对半搜索的迭代算法

递归函数效率低, 常使用相应的迭代算法. mid, left, right均为元素下标, 如果当前表不为空, 则令x与l[mid]比较. 若两者相等, 则搜索成功. 若前者小于后者, 则继续查找左半部分, 否 则查找右半部分. 下标范围分别为[left, mid - 1], [mid + 1, right]. 如果当前搜索表为空表, 搜索失败返回NotPresent. 实现代码: #include "iostream" #include "cstdio" #incl

ListSet_无序表搜索

无序表搜索就是一个个的遍历, 从头开始逐个检查, 直到表中关键字值等于给定关键字值, 则查找成功. 或者查完整个表, 查找失败为止. 搜索失败的平均搜索长度:(n + 1) / 2. 实现代码: #include "iostream" #include "cstdio" #include "cstring" #include "algorithm" #include "assert.h" using nam

CF888E Maximum Subsequence-折半搜索

题意:给一个数列和m,在数列任选若干个数,使得他们的和对m取模后最大. 注意到n<=35,直接枚举状态不行,考虑meeting in the middle. 那么的话我们直接暴力枚举两边的状态就好了,不过我们记录的是取模后的sum.. 现在主要解决合并答案的问题.都是套路是吧... 我们容易发现,如果我们枚举一边的答案, 另外一边有用的答案(有可能和当前枚举的构成最后答案的)仅有两种可能, 一种是和当前答案加起来<模数的,那么显然最大的那个最优, 另一种是>模数的,由于之前取了模,和不会

迷宫寻址中深度优先搜索的递归和非递归算法比较

巧若拙(欢迎转载,但请注明出处:http://blog.csdn.net/qiaoruozhuo) 本文只探究迷宫寻址中深度优先搜索的递归和非递归算法比较,其他相关代码详见<迷宫问题(巧若拙)>http://blog.csdn.net/qiaoruozhuo/article/details/41020745 深度优先搜索的递归算法是很容易实现的,只需设置一个驱动函数,然后递归调用子函数就可以了. 代码如下: int DeepSearchWay()//寻找路径:深度搜索 { CopyMiGong

定制WinEdt 优化Latex输入

前一个礼拜忙着准备讨论班的演示稿,顺带还有单位的一门考试的试题需要排版整理,所以微博更新的速度又被拖后了.说实话,Latex这种"所想即所得"的排版系统对人的确是一种折磨,它并不适合快速的文档编辑,倒是适合我们这种具有强烈强迫症倾向的人用来欣赏.所谓"慢工出细活",用Latex编辑文稿.书籍排版是集腋成裘的勾当,有许多东西是在这种折磨的过程中慢慢积累出来的.我在几年的考试命题出题过程中,从最开始的Word+Mathtype逐渐过渡到Word+Aurora,最后还是

JAVA递归

1.递归作为一种算法在程序设计语言中广泛应用,是指函数/过程/子程序在运行过程中直接或间接调用自身而产生的重入现象. 2.递归算法一般用于解决三种问题: 1)数据的定义是按递归定义的.( Fibonacci(斐波那契)函数). 2)问题解决按递归算法实现.(回溯) 3)数据的结构形式是按递归定义的.(数的便利,图的搜索) 递归算法解题通常显得很简洁,但递归算法解题的运行效率较低.所以一般不提倡用递归算法设计程序. 在递归调用的过程当中系统为每一层的返回点.局部量等开辟了栈来存储.递归次数过多容易

10月18号 蒟蒻的流水账

11:06:11 早上开完了开幕式,来到机房写了昨天考的第三题,用了费用流来写没有用贪心(正好复习一下各种流) 好想去看比赛啊. 下午两点十五分有我得去跨栏,跑完后还要神不知鬼不觉地溜回机房参加老师三点的模拟考试(不能让老师知道我偷偷参加了校运会)不过其实机房的好多小伙伴今天早上都没有来(以比赛为由,偷偷溜去看比赛). 我早上千辛万苦地把相机和三角架放在共享单车的篮子里,一路小心翼翼地骑到学校,结果却只为借给别人用!(太善良,不会拒绝别人) 自己窝在机房都快进化成硅基生物了. 好想摄影,毕竟自己

教材快速浏览

第一章:计算系统的运作方式以及一至五代软件的运行机制是什么 第二章:二进制.八进制和十六进制应当怎么应用和互相转换 第三章:怎么表示和储存计算机管理的各种类型的数据 第四章:不同门的作用以及电路如何由门组成 第五章:构成计算机的部件的特征.作用是什么 第六章:伪代码的算法功能及翻译是什么 第七章:循环.数据.搜索.递归算法如何应用,快速排序的优点是什么 第八章:二叉树.二叉检索树的区别是什么,又分别怎么应用 第九章:面向对象设计过程如何应用,不同范型的优缺点 第十章:计算机操作系统的构造和它们分

每天算法一丁点(3)--递归算法应用:半数集

半数集问题 题意:给定一个自然数n,由n开始依次产生半数集 set(n),set(n) 的定义如下: n 是 set(n) 中的元素 在 n 的左边添加一个自然数,但该自然数不能超过最近添加的数的一半 按此规律添加,直到不能添加自然数为止 例如:set(6) = {6,16,26,126,36,136} 求半数集中元素的个数 分析:给定一个数n,那么在其前可以添加的数有从 1 到  m = n/2 .在这 m 个数中,m 前可以添加的数又有从 1 到 s = m/2 . 因此,用递归+循环解决.