二分法查找有序表的通用算法(可查链表,数组,字符串...等等)

find_binary函数 

注意事项:

(1)你设计的迭代器模板中必须有using value_type = T,且有加减运算功能,其本上能与C++标准库std中一样。

(2)集合必须是有序的。

下面是函数代码:

/// <summary>
/// 二分法查找有序表的通用算法(可查链表,数组,字符串...等等)
/// 例子:
///  vector<int> v;
///  find_binary(b.begin(),v.end(),3);  // Inde返回 (-1, *Iterator == ?)
/// 
///  vector<int> v = {3};
///  find_binary(b.begin(),v.end(),3);  // 返回  (Index == 0, *Iterator == 3)
///  
///  const char* sz = "abcdefgb";
///  auto f3 = lf::find_binary(sz, sz + 8, 'c');  //返回  (Index == 2, *Iterator == c)
/// </summary>
/// <typeparam name="IteratorType">迭代器类型</typeparam>
/// <typeparam name="value_type">值类型</typeparam>
/// <param name="itBegin">开始位置</param>
/// <param name="itEnd">结束位置</param>
/// <param name="vtFindValue">查找值</param>
/// <returns>返回索引与指向vtFindValue的迭代器</returns>
/// 创建时间: 2024-07-03     最后一修改时间:2024-07-03  (基本上已经测试)
template<typename IteratorType,typename value_type = IteratorType::value_type>
FindResult<IteratorType> find_binary(const IteratorType& itBegin, const IteratorType& itEnd, const value_type& vtFindValue)
{FindResult<IteratorType> fr;  auto beg = itBegin;auto end = itEnd;int nCount = end - beg;if (nCount == 0) return fr;if (*(itEnd-1) > *itBegin) {//从小到大排列auto mid = beg + nCount / 2;while (mid != itEnd){if(*mid == vtFindValue){fr.Iter = mid;fr.Index = mid - itBegin;return fr;}if (vtFindValue < *mid)end = mid;elsebeg = mid + 1;  //在mid之后查找mid = beg + (end - beg) / 2;   //新的中间点}	 }else{ //从大到小排列 auto mid = beg + nCount / 2;while (mid != itEnd) {if (*mid == vtFindValue) {fr.Iter = mid;fr.Index = mid - itBegin;return fr;}if (vtFindValue > *mid)end = mid;elsebeg = mid + 1;  //在mid之后查找mid = beg + (end - beg) / 2;   //新的中间点}}return fr;
}

例子代码:

 
int main()
{std::vector<int> v1 = { 1,2,3,4,5,6 ,7,8,9,10 };_DList<int> d1 = { 1,2,3,4,5,6 ,7,8,9,10 };const char* sz = "abcdefgb";auto f1 = lf::find_binary(v1.begin(), v1.end(), 3);cout << *(f1.Iter) << "\n";cout << f1.Index << "\n";cout << "----------" << "\n";auto f2 = lf::find_binary(d1.begin(), d1.end(), 3);cout << *(f2.Iter) << "\n";cout << f2.Index << "\n";cout << "----------" << "\n";auto f3 = lf::find_binary(sz, sz + 8, 'c');cout << *(f3.Iter) << "\n";cout << f3.Index << "\n";cout << "----------" << "\n";std::vector<int> v2 = { 10,9,8,7,6,5,4,3,2,1 };auto f4 = lf::find_binary(v2.begin(), v2.end(), 3);cout << *(f4.Iter) << "\n";cout << f4.Index << "\n";cout << "----------" << "\n";}

输出:

完整代码如下:

/*******************************************************************************************
文件名						: _AlgorithmLibrary.h功能							: 算法库作者							: 李锋手机							: 13828778863Email						: ruizhilf@139.com创建时间						: 2024年07月02日最后一次修改时间				:  2024年07月02日
*********************************************************************************************/
#pragma once//Algorithm library  算法库#include "_Macro.h"/*****************************************************************************排序****************************************************************************///排序
//参考:https://blog.csdn.net/qq_45615577/article/details/115257685//排序的概念
/*
排序:所谓排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作。
稳定性:假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次 序保持不变,即在原序列中,r[i] = r[j],且r[i]在r[j]之前,而在排序后的序列中,r[i]仍在r[j]之前,则称这种排 序算法是稳定的;否则称为不稳定的。
内部排序:数据元素全部放在内存中的排序。
外部排序:数据元素太多不能同时放在内存中,根据排序过程的要求不能在内外存之间移动数据的排序。
————————————————版权声明:本文为博主原创文章,遵循 CC 4.0 BY - SA 版权协议,转载请附上原文出处链接和本声明。原文链接:https ://blog.csdn.net/qq_45615577/article/details/115257685
*/
_LF_BEGIN_/// <summary>
/// 选择排序---直接选择排序
/// 每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,
/// 直到全部待排序的 数据元素排完 。
/// 找出序列中的最小关键字,然后将这个元素与序列首端元素交换位置。例如,序列前i个
/// 元素已经有序,从第i + 1到第n个元素中选择关键字最小的元素,假设第j个元素为最小
/// 元素,则交换第j个元素与第i + 1个元素的位置。依次执行此操作,直到第n - 1个元素
/// 也被确定。
/// </summary>
/// <typeparam name="T">类型</typeparam>
/// <param name="pData">开始位置</param>
/// <param name="nCount">元素个数</param>
/// <param name="so">排序顺序,默认从小到大</param>
/// 创建时间: 2024-07-01     最后一修改时间:2024-07-01
/// 参考网址:https://blog.csdn.net/qq_45615577/article/details/115257685 
template<class T>
void sort_selection(T* pData, const size_t& nCount, const bool& bMinMax = true)
{/*7 4 5 9 8 2 11 4 5 9 8 2 72 5 9 8 4 74 9 8 5 75 8 9 77 9 88 9在 [0 , n-1] 中找出最小的放在第一位在 [1 , n-1] 中找出最小的放在第二位...*/if (pData == null || nCount == 0) return;int nSortedCount = 0;  //已排序好的个数if (bMinMax) {while (nSortedCount < nCount) {int  minIndex = nSortedCount;//在[nStart, nCount-1] 中找出最小值for (int n = nSortedCount + 1; n < nCount; ++n) {if (*(pData + n) < *(pData + minIndex)) {minIndex = n;}}if (minIndex != nSortedCount) {T tmp = *(pData + minIndex);*(pData + minIndex) = *(pData + nSortedCount);*(pData + nSortedCount) = tmp;}++nSortedCount;}}else {while (nSortedCount < nCount) {int  maxIndex = nSortedCount;//在[nStart, nCount-1] 中找出最大值for (int n = nSortedCount + 1; n < nCount; ++n) {if (*(pData + n) > *(pData + maxIndex)) {maxIndex = n;}}if (maxIndex != nSortedCount) {T tmp = *(pData + maxIndex);*(pData + maxIndex) = *(pData + nSortedCount);*(pData + nSortedCount) = tmp;}++nSortedCount;}}}/// <summary>
/// 返回最小值的位置
///		lf::_DList<int> d1 = { 1,3,5,8,2,0 };
///		lf::_DList<int> d2 = { 1 };
///		lf::_DList<int> d3 = { };
///		vector<int> v = { 1,3,5,8,2,0 };
///
///		_pin(*lf::Min(d1.begin(), d1.end()));  //输出: 0
///		_pin(*lf::Min(d2.begin(), d2.end()));  //输出: 1
///		_pin(*lf::Min(d3.begin(), d3.end()));  //报错,最少一个元素
///
///		_pin(*lf::Min(v.begin(), v.end()));  //输出: 0
/// 
/// 	_string s = _t("sdwsffa");
///		_pin(*lf::Min(s.begin(), s.end()));  //输出: a/// </summary>
/// <typeparam name="IteratorClass"></typeparam>
/// <param name="itBegin"></param>
/// <param name="itEnd"></param>
/// <returns></returns>
/// 创建时间: 2024-07-02     最后一修改时间:2024-07-02
template<typename IteratorClass>
IteratorClass Min(IteratorClass itBegin, IteratorClass itEnd) {assert(itBegin != itEnd);IteratorClass result = itBegin;while (itBegin != itEnd) {if (*result > *itBegin)result = itBegin;++itBegin;}return result;
}/// <summary>
/// 
/// </summary>
/// <typeparam name="IteratorClass"></typeparam>
/// <param name="itBegin"></param>
/// <param name="itEnd"></param>
/// <returns></returns>
/// 创建时间: 2024-07-02     最后一修改时间:2024-07-02
template<typename IteratorClass>
IteratorClass Max(IteratorClass itBegin, IteratorClass itEnd) {assert(itBegin != itEnd);IteratorClass result = itBegin;while (itBegin != itEnd) {if (*result < *itBegin)result = itBegin;++itBegin;}return result;
}/// <summary>
/// 
/// </summary>
/// <typeparam name="IteratorClass"></typeparam>
/// <param name="it1"></param>
/// <param name="it2"></param>
/// 创建时间: 2024-07-02     最后一修改时间:2024-07-02
template<typename IteratorClass>
void Swap(IteratorClass it1, IteratorClass it2) {//std::cout << "===================================\n";//_pin(*it1);//_pin(*it2);auto tmp = *it1;  //如果*it2是 int& 则,tmp 的类型是int, 并不是int&。*it1 = *it2;*it2 = tmp;//_pin(*it1);//_pin(*it2);//std::cout << "===================================\n";
}/// <summary>
/// 	lf::_DList<int> d4 = {1,2,3,6,5,4};
///		lf::sort_selection(d4.begin(), d4.end(), _SortOrder::s_Minmax);
///		_pcn(d4);  //输出:d4={1,2,3,4,5,6}
///		lf::sort_selection(d4.begin(), d4.end(), _SortOrder::s_Maxmin);
///		_pcn(d4); //输出:d4={6,5,4,3,2,1}
/// 
///		_string s2 = _t("_DListNodeIterator,abcd,efg");
///		_pcn(s2); //s2=_DListNodeIterator,abcd,efg
///		lf::sort_selection(s2.begin(), s2.end(), _SortOrder::s_Minmax);
///		_pcn(s2); //s2=,,DILN_aabcddeeefgioorrsttt
///		lf::sort_selection(s2.begin(), s2.end(), _SortOrder::s_Maxmin);
///		_pcn(s2); //s2=tttsrrooigfeeeddcbaa_NLID,,
/// </summary>
/// <typeparam name="IteratorClass"></typeparam>
/// <param name="itBegin"></param>
/// <param name="itEnd"></param>
/// <param name="so"></param>
/// 创建时间: 2024-07-01     最后一修改时间:2024-07-02(已测试)
template<typename IteratorClass>
void sort_selection(IteratorClass itBegin, IteratorClass itEnd, const bool& bMinMax = true)
{/*7 4 5 9 8 2 11 4 5 9 8 2 72 5 9 8 4 74 9 8 5 75 8 9 77 9 88 97 2 2 2 2 2 22 7 2 2 2 2 22 7 2 2 2 22 7 2 2 22 7 2 22 7 22 7在 [0 , n-1] 中找出最小的放在第一位在 [1 , n-1] 中找出最小的放在第二位...*/if (bMinMax) {while (itBegin != itEnd) {//在[itBegin + 1, itEnd] 中找出最小值,与itBegin交换		 Swap(itBegin, Min(itBegin, itEnd));++itBegin;}}else {while (itBegin != itEnd) {//在[itBegin + 1, itEnd] 中找出最小值,与itBegin交换Swap(itBegin, Max(itBegin, itEnd));++itBegin;}}
}/*****************************************************************************查找顺序查找二分查找插值查找、斐波那契查找分块查找哈希查找树表查找****************************************************************************/
template<typename IteratorType>
struct FindResult
{/// <summary>/// 如果没找到 Index == -1/// </summary>int Index;IteratorType Iter;public:inline FindResult(){Index = -1;}inline FindResult(const FindResult& r){Index = r.Index;Iter = r.Iter;}
};/// <summary>
/// 顺序查找
/// 
/// 注意:
///		如果是向后查找,则返回的索引是以itFirst开始算来,第一个为 0,即itFirst为0。
///		如果是向前揸找,则返回的索引是以itLast开始算起,第一个,即itLast为0。
///		 
/// </summary>
/// <typeparam name="IteratorType"></typeparam>
/// <typeparam name="DataType"></typeparam>
/// <param name="itBegin"></param>
/// <param name="itEnd"></param>
/// <param name="tValue"></param>
/// <param name="bBackward"></param>
/// <returns></returns>
/// 创建时间: 2024-07-03     最后一修改时间:2024-07-03
template<typename IteratorType, typename DataType>
FindResult<IteratorType> find_sequential(IteratorType itFirst, IteratorType itLast,const DataType& tFindValue, const bool& bBackward = true)
{FindResult<IteratorType> fr;fr.Index = -1;int n = 0;if (bBackward) {  //向后while (true){if (*itFirst == tFindValue) {fr.Index = n;fr.Iter = itFirst;break;}++n;++itFirst;if (itFirst == itLast) break;}}else {while (true){if (*itLast == tFindValue) {fr.Index = n;fr.Iter = itLast;break;}++n;--itLast;if (itFirst == itLast) break;}}return fr;
}/// <summary>
/// 集合类必须带有 begin() 和 end() 函数
/// 例子:
///		std::vector<int> v = { 1,2,3,23,435,4646,34 };
///		lf::_DList<int> d = { 1,2,3,23,435,4646,34 };
///		if (lf::IsExists(d, 23))
///		{
///		cout << "存在23.\n";
///		}
///		if (lf::IsExists(v, 55))
///		{
///			cout << "存在55.\n";
///		}
/// </summary>
/// <typeparam name="value_type"></typeparam>
/// <typeparam name="CollectionClass"></typeparam>
/// <param name="col"></param>
/// <param name="value"></param>
/// <returns></returns>
/// 创建时间: 2024-07-03     最后一修改时间:2024-07-03
template<typename CollectionClass, typename value_type = CollectionClass::value_type>
bool IsExists(const CollectionClass& col, const value_type& value)
{auto itbegin = col.begin();auto itend = col.end();while (itbegin != itend){if (*itbegin == value)return true;++itbegin;}return false;
}/// <summary>
/// 二分法查找有序表的通用算法(可查链表,数组,字符串...等等)
/// 例子:
///  vector<int> v;
///  find_binary(b.begin(),v.end(),3);  // Inde返回 (-1, *Iterator == ?)
/// 
///  vector<int> v = {3};
///  find_binary(b.begin(),v.end(),3);  // 返回  (Index == 0, *Iterator == 3)
///  
///  const char* sz = "abcdefgb";
///  auto f3 = lf::find_binary(sz, sz + 8, 'c');  //返回  (Index == 2, *Iterator == c)
/// </summary>
/// <typeparam name="IteratorType">迭代器类型</typeparam>
/// <typeparam name="value_type">值类型</typeparam>
/// <param name="itBegin">开始位置</param>
/// <param name="itEnd">结束位置</param>
/// <param name="vtFindValue">查找值</param>
/// <returns>返回索引与指向vtFindValue的迭代器</returns>
/// 创建时间: 2024-07-03     最后一修改时间:2024-07-04  (初步测试)
template<typename IteratorType,typename value_type = IteratorType::value_type>
FindResult<IteratorType> find_binary(const IteratorType& itBegin, const IteratorType& itEnd, const value_type& vtFindValue)
{FindResult<IteratorType> fr;  auto beg = itBegin;auto end = itEnd;int nCount = end - beg;if (nCount == 0) return fr;if (*(itEnd-1) > *itBegin) {//从小到大排列auto mid = beg + nCount / 2;while (mid != itEnd){if(*mid == vtFindValue){fr.Iter = mid;fr.Index = mid - itBegin;return fr;}if (vtFindValue < *mid)end = mid;elsebeg = mid + 1;  //在mid之后查找mid = beg + (end - beg) / 2;   //新的中间点}	 }else{ //从大到小排列 auto mid = beg + nCount / 2;while (mid != itEnd) {if (*mid == vtFindValue) {fr.Iter = mid;fr.Index = mid - itBegin;return fr;}if (vtFindValue > *mid)end = mid;elsebeg = mid + 1;  //在mid之后查找mid = beg + (end - beg) / 2;   //新的中间点}}return fr;
}_LF_END_

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/866415.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

一次建表语句触发的ORA-600报错分析

​ 某次在客户Oracle数据库执行一条建表语句时&#xff0c;报出ORA-600错误。 报错代码如下&#xff1a; ORA-00600: 内部错误代码, 参数: [rwoirw: check ret val], [], [], [], [], [], [], [], [], [], [], [] 相关的建表语句如下&#xff1a; ​ 在报错发生后&#xff0c;…

Android studio开发入门教程详解(复习)

引言 本文为个人总结Android基础知识复习笔记。如有不妥之处&#xff0c;敬请指正。后续将持续更新更多知识点。 文章目录 引言UITextView文本基本用法实际应用常用属性和方法 Button按钮处理点击事件 EditText输入框基本属性高级特性 ImageView图片ImageView的缩放模式 Prog…

Qt中udp指令,大小端,帧头帧尾实际示例

前言 虽然QT中&#xff0c;udp发送和接收&#xff0c;其实非常简单&#xff0c;但是实际工作中&#xff0c;其实涉及到帧头帧尾&#xff0c;字节对齐&#xff0c;以及大小端序的问题。比如网络中&#xff0c;正规的一般都是大端序&#xff0c;而不是小端序&#xff0c;大多数的…

不到 5 元的随身 WiFi 刷 Debian 系统 做轻量家庭服务器

本文首发于只抄博客,欢迎点击原文链接了解更多内容。 前言 前不久在某宝均价 5 元买了两个随身 WiFi,拆机看了看丝印都是 MSM8916 ,正好是红米 2 同款的骁龙 410 的芯片,可以刷个 Debian 当作家庭服务器来跑一些轻量的服务。 不过手气不是很好,两个都是 512M + 4G 的配置…

单机安装基于LNMP结构的WordPress网站 web与数据库服务分离

网站的类型&#xff1a; Jave:LNMT PHP:LNMP Python: LNMU 项目部署&#xff1a; 1.项目的类型&#xff08;项目的开发语言&#xff09; 2.项目运营平台的技术选择 3.尽快让项目运行起来 all in one部署 4. 架构的优化 配置ansible管理环境 配置nginx 配置数据库服务…

day11_homework_need2submit

Homework 编写—个将ts或mp4中视频文件解码到yuv的程序 yuv数据可以使用如下命令播放: ffplay -i output yuv-pix_fmt yuv420p-s 1024x436 要求: ffmpeg解析到avpacket并打印出pts和dts字段完成解码到avframe并打印任意字段完成yuv数据保存 // teminal orders on bash cd ex…

11.SQL注入-盲注基于(base on boolian)

SQL注入-盲注基于boolian案例利用 首先总结一下sql语句中的函数意思 #查看当前所在的数据库 mysql> select database(); ------------ | database() | ------------ | pikachu | ------------ 1 row in set (0.00 sec)#函数substr里1是从第几位开始取字符&#xff0c;2…

油猴Safari浏览器插件:Tampermonkey for Mac 下载

Tampermonkey 是一个强大的浏览器扩展&#xff0c;用于运行用户脚本&#xff0c;这些脚本可以自定义和增强网页的功能。它允许用户在网页上执行各种自动化任务&#xff0c;比如自动填写表单、移除广告、改变页面布局等。适用浏览器&#xff1a; Tampermonkey 适用于多数主流浏览…

Java的进程和线程

一Java的进程 二Java的线程 多线程 ◆如果在一个进程中同时运行了多个线程&#xff0c;用来完成不同的工作&#xff0c;则称之为“多线程”。 ◆多个线程交替占用CPU资源&#xff0c;而非真正的并行执行。 ◆多线程好处。 ◆充分利用CPU的资源。 ◆简化编程模型。 ◆良好的用…

3-1 激活函数和神经网络思想

3-1 激活函数和神经网络思想 主目录点这里

【抽代复习笔记】26-群(二十):子群的定义以及第一、第二判定定理

子群 定义1&#xff1a;(G,o)是一个群&#xff0c;H是G的非空子集&#xff0c;若H关于G的乘法o也能作成群&#xff08;满足群的判定定理&#xff1a;封闭性、结合律、单位元、逆元&#xff09;&#xff0c;则称H为G的子群&#xff0c;记作H ≤ G&#xff1b;若H是G的真子集&am…

【启明智显分享】手持遥控器HMI解决方案:2.8寸触摸串口屏助力实现智能化

现代生活不少家居不断智能化&#xff0c;但是遥控器却并没有随之升级。在遥控交互上&#xff0c;传统遥控器明显功能不足&#xff1a;特别是大屏智能电视&#xff0c;其功能主要由各种APP程序实现。在电脑上鼠标轻轻点击、在手机上触摸屏丝滑滑动&#xff0c;但是在电视上这些A…

SpringBoot 启动流程二

SpringBoot启动流程二 我们首先查看构造方法 SpringApplication 我们发现这个构造方法还是在SpringApplication类里面 这个构造方法还是调用了自身的构造方法 传入了两个参数 第一个参数叫resourceLoader 传入的是一个资源加载器 要从外部读入东西 这个方法通过this关键字…

c++纵横字谜

1.实现一个纵横字谜 2.支持14x14的网格 3.可以查看答案 4.猜测错误会提示答案信息 5.从txt读取词汇 6.每次游戏开始 随机生成纵横字谜 n’h

leetcode216.组合总和III、40.组合总和II、39.组合总和

216.组合总和III 找出所有相加之和为 n 的 k 个数的组合&#xff0c;且满足下列条件&#xff1a; 只使用数字1到9 每个数字 最多使用一次 返回 所有可能的有效组合的列表 。该列表不能包含相同的组合两次&#xff0c;组合可以以任何顺序返回。 示例 1: 输入: k 3, n 7 输出…

deepin UOS AI 如何配置自定义模型

科技飞速发展的今天&#xff0c;操作系统作为计算机系统的灵魂&#xff0c;其每一次的更新与变革都牵动着无数用户的心弦。近日&#xff0c;开源操作系统 deepin 迎来了一次重大更新&#xff0c;这次更新不仅在性能上进行了全面优化&#xff0c;更在 AI 智能化方面迈出了划时代…

【解决方案】笔记本电脑屏幕亮度调节失效(Dell G15 5510 使用Fn调节)

目前解决方案&#xff1a;使用驱动总裁&#xff08;其他的驱动安装软件应该也可以&#xff0c;个人觉得这个好用&#xff09;&#xff0c;更新显卡驱动即可。如图所示本人更新了Intel UHD Graphics核显驱动&#xff0c;功能回复正常。 使用Fn快捷键调节亮度如图所示&#xff0…

ARIES,数据恢复算法,万变不离其宗...

今天来聊两个问题&#xff1a; 1. 如果缓冲池&#xff08;buffer pool&#xff09;满了&#xff0c;哪些数据页&#xff08;page&#xff09;要刷盘&#xff0c;哪些数据页不刷盘&#xff1f; 2. 数据库崩了&#xff0c;怎么利用检查点&#xff08;checkpoint&#xff09;与预写…

Django 定义模型执行迁移

1&#xff0c;创建应用 Test/app8 python manage.py startapp app8 2&#xff0c;注册应用 Test/Test/settings.py 3&#xff0c;配置路由 Test/Test/urls.py from django.contrib import admin from django.urls import path, includeurlpatterns [path(app8/, include(a…

硅纪元视角 | AI纳米机器人突破癌症治疗,精准打击肿瘤细胞

在数字化浪潮的推动下&#xff0c;人工智能&#xff08;AI&#xff09;正成为塑造未来的关键力量。硅纪元视角栏目紧跟AI科技的最新发展&#xff0c;捕捉行业动态&#xff1b;提供深入的新闻解读&#xff0c;助您洞悉技术背后的逻辑&#xff1b;汇聚行业专家的见解&#xff0c;…