(2011.12.07) 09_有序表的折半查找.cpp

本文详细介绍了折半查找与折半插入排序的原理、思想、使用场景及优化效果,通过代码实例深入浅出地展示了这两种算法的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 
// 09_有序表的折半查找.cpp

/**
 * -> 适用条件:
 * 1. 有序表:就是指表中的数据已经按升序或者是降序排好序的表。
 * 2. 知识联系:就个人理解,这跟之前所写过的折半排序的思想基本上是一样的,唯一不同的仅是这里面的数据已经排好序了,只需要找到匹配元素就可以了。
 * 3. 思想亦是一样,只是跟折半插入排序有点小改动,具体可以参考下面的第4点内容。
 **/

/**
 * -> 折半插入排序思想分析:
 * 1. 跟名字差不多,也是插入排序的一种,只是跟普通的插入排序有点不同。
 * 2. 在普通的插入排序中,新的元素需要插入到已排好序的数组中时,是对数组中的元素逐个比较,得出位置。
 * 3. 折半插入排序也是一样需要将新元素插入到已排好序的数组中,只是这时不是对元素进行逐个比较,
 *    而是在插入之前先找到正确的位置,然后直接插入到那个位置当中。
 * 4. 所谓折半查找,也就是将一个数组分成一半来查找,准确地来说,是将数组分成两个一半来查找,
 *    假设有数组 0, 0, 0, 0, 0, 0 那么,现在的查找方式是,设定左右边界 -> |0, 0, 0 | 0, 0, 0 |<- .从中间开始与新元素比较。
 * 5. 刚刚刚那个 "|" 正是需要插入的位置了,假如发现左边或右边的元素符合比较条件,那么,它会让左边或右边的"|"移动位置至中间的"|"。
 *    从而使左边或者右边的"|"移到中间的"|"的左边一位或右边一位,如果数组较大,那么跳跃性就明显这就是折半插排序的主要思想了。
 * -> 使用折半插入排序的原因:
 * 1. 一般来说,一个算法出来,无非就是两个原因,1. 解决需要解决的问题, 2. 优化需要解决的问题
 *    在这个排序方法中,主要是优化原来的插入排序的问题,使排序的效率更高,平均情况下总比较次数约为n*n/4
 **/


#include <iostream>
#include <vector>
#include <conio.h>		// _getch();
					
using std::cin;			// using 声明
using std::cout;
using std::endl;
using std::vector;


// ________________________ 主函数 _______________________________
int main()
{
	void InsertArr(vector<double> & test);
	void HalfSearch(vector<double> & test, double x);
	void ShowArr(vector <double> & test);
	bool testagain(true);
	char testagainjudge;
	vector<double> testArr;				// 用于测试的数组
	do
	{
		cout << "------------------------- 现在开始数组的折半查找测试 ---------------------------\n";
		cout << "-> 说明:该测试共分为三个步骤:输入数组元素(系统内部) -> 输入查找元素 -> 结果.\n";
		// 插入
		InsertArr(testArr);
		ShowArr(testArr);
		cout << endl;
		// 查找
testagain:
		cout << "\n -> 请输入需要查找的数据:";
		double x;
		cin >> x;
		while (!cin)
		{
			cin.sync();
			cin.clear();
			cin >> x;
		}
		HalfSearch(testArr, x);
		cout << endl;

		cout << "-> 如需重新测试,请按字符'a',否则请按任意键退出...\n\n";
		testagainjudge = _getch();
		if (testagainjudge == 'a')
		{
			cin.sync();
			testagain = true;
			goto testagain;

		}
		else 
		{
			testagain = false;
		}
	}while (testagain);
	return 0;
}

/**
 * 子程序名称:InsertArr
 * 子程序返回类型:void
 * 子程序入口参数:vector<double> &
 * 子程序功能:由系统设定N个数值,程序将其保存入vector<double>入口参数处。
 **/
void InsertArr(vector<double> & test)
{
    for ( unsigned int i = 1; i < 10; ++i)
    {
		test.push_back(i);
     }
    return;
} 


/**
 * 子程序名称:HalfSearch
 * 子程序返回类型:void
 * 子程序入口参数:vector<double> &, double x
 * 子程序功能:从vector<double>&升序数组中搜索出是否有值与x相关,并向用户反馈信息
 **/
void HalfSearch(vector<double> & test, double x)
{
	int n = static_cast<int>(test.size());
	int left(0);
	int right(n - 1);
	while (left <= right)
	{
		int middle = (left + right) / 2;
		if (test[middle] == x)
		{
			cout << "\n恭喜,从表中的第" << middle + 1 << "个位置找到该元素。\n";
			return;
		}
		else if ( test[middle] > x)		// 该表原顺序是从小到大排序的。
		{								// 当该元素比数组中的元素小时,则向右缩进查找区间
			right = middle - 1;
		}
		else						// 当该元素比数组中的元素大时,则向左缩进查找区间
		{
			left = middle + 1;
		}
	}
	// 当left比right大,也就是说将该表左右总区间扫描了一次后,还是未能发现在区间内的元素,则此时该查找元素不存在于表中。
	cout << "\n很遗憾,未能从表中找到该元素。";	
	return;
}

/**
 * 子程序名称:ShowArr
 * 子程序返回类型:void
 * 子程序入口参数:vector<double> &
 * 子程序功能:遍历并显示vector<double>&。
 **/
void ShowArr(vector <double> & test)
{
     cout << "-> 现在开始显示确认刚刚所输入的数组顺序:\n";
     cout << "-> ";
     vector<double>::const_iterator be(test.begin());
     vector<double>::const_iterator en(test.end());
     while ( be != en)
     {
           cout << *be++ << " ";
	 }
      return;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值