// 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;
}
(2011.12.07) 09_有序表的折半查找.cpp
最新推荐文章于 2021-05-18 09:04:01 发布