当前位置:首页 » 操作系统 » 搜索算法的实现

搜索算法的实现

发布时间: 2022-04-23 04:37:52

❶ C语言题目: 搜索算法的设计与实现

呵呵什么时候截止?可以尝试完成,

❷ 搜索引擎中索引时怎么实现的

随着互联网的迅猛发展、WEB信息的增加,用户要在信息海洋里查找自己所需的信息,就象大海捞针一样,搜索引擎技术恰好解决了这一难题(它可以为用户提供信息检索服务)。搜索引擎是指互联网上专门提供检索服务的一类网站,这些站点的服务器通过网络搜索软件(例如网络搜索机器人)或网络登录等方式,将Intemet上大量网站的页面信息收集到本地,经过加工处理建立信息数据库和索引数据库,从而对用户提出的各种检索作出响应,提供用户所需的信息或相关指针。用户的检索途径主要包括自由词全文检索、关键词检索、分类检索及其他特殊信息的检索(如企业、人名、电话黄页等)。下面以网络搜索机器人为例来说明搜索引擎技术。
1.网络机器人技术
网络机器人(Robot)又被称作Spider、Worm或Random,核心目的是为获取Intemet上的信息。一般定义为“一个在网络上检索文件且自动跟踪该文件的超文本结构并循环检索被参照的所有文件的软件”。机器人利用主页中的超文本链接遍历WWW,通过U趾引用从一个HT2LIL文档爬行到另一个HTML文档。网上机器人收集到的信息可有多种用途,如建立索引、HIML文件合法性的验证、uRL链接点验证与确认、监控与获取更新信息、站点镜像等。
机器人安在网上爬行,因此需要建立一个URL列表来记录访问的轨迹。它使用超文本,指向其他文档的URL是隐藏在文档中,需要从中分析提取URL,机器人一般都用于生成索引数据库。所有WWW的搜索程序都有如下的工作步骤:
(1)机器人从起始URL列表中取出URL并从网上读取其指向的内容;
(2)从每一个文档中提取某些信息(如关键字)并放入索引数据库中;
(3)从文档中提取指向其他文档的URL,并加入到URL列表中;
(4)重复上述3个步骤,直到再没有新的URL出现或超出了某些限制(时间或磁盘空间);
(5)给索引数据库加上检索接口,向网上用户发布或提供给用户检索。
搜索算法一般有深度优先和广度优先两种基本的搜索策略。机器人以URL列表存取的方式决定搜索策略:先进先出,则形成广度优先搜索,当起始列表包含有大量的WWW服务器地址时,广度优先搜索将产生一个很好的初始结果,但很难深入到服务器中去;先进后出,则形成深度优先搜索,这样能产生较好的文档分布,更容易发现文档的结构,即找到最大数目的交叉引用。也可以采用遍历搜索的方法,就是直接将32位的IP地址变化,逐个搜索整个Intemet。
搜索引擎是一个技术含量很高的网络应用系统。它包括网络技术、数据库技术动标引技术、检索技术、自动分类技术,机器学习等人工智能技术。
2.索引技术
索引技术是搜索引擎的核心技术之一。搜索引擎要对所收集到的信息进行整理、分类、索引以产生索引库,而中文搜索引擎的核心是分词技术。分词技术是利用一定的规则和词库,切分出一个句子中的词,为自动索引做好准备。目前的索引多采用Non—clustered方法,该技术和语言文字的学问有很大的关系,具体有如下几点:
(1)存储语法库,和词汇库配合分出句子中的词汇;
(2)存储词汇库,要同时存储词汇的使用频率和常见搭配方式;
(3)词汇宽,应可划分为不同的专业库,以便于处理专业文献;
(4)对无法分词的句子,把每个字当作词来处理。
索引器生成从关键词到URL的关系索引表。索引表一般使用某种形式的倒排表(1nversionUst),即由索引项查找相应的URL。索引表也要记录索引项在文档中出现的位置,以便检索器计算索引项之间的相邻关系或接近关系,并以特定的数据结构存储在硬盘上。
不同的搜索引擎系统可能采用不尽相同的标引方法。例如Webcrawler利用全文检索技术,对网页中每一个单词进行索引;Lycos只对页名、标题以及最重要的100个注释词等选择性词语进行索引;Infoseek则提供概念检索和词组检索,支持and、or、near、not等布尔运算。检索引擎的索引方法大致可分为自动索引、手工索引和用户登录三类。
3. 检索器与结果处理技术
检索器的主要功能是根据用户输入的关键词在索引器形成的倒排表中进行检索,同时完成页面与检索之间的相关度评价,对将要输出的结果进行排序,并实现某种用户相关性反馈机制。
通过搜索引擎获得的检索结果往往成百上千,为了得到有用的信息,常用的方法是按网页的重要性或相关性给网页评级,进行相关性排序。这里的相关度是指搜索关键字在文档中出现的额度。当额度越高时,则认为该文档的相关程度越高。能见度也是常用的衡量标准之一。一个网页的能见度是指该网页入口超级链接的数目。能见度方法是基于这样的观点:一个网页被其他网页引用得越多,则该网页就越有价值。特别地,一个网页被越重要的网页所引用,则该网页的重要程度也就越高。结果处理技术可归纳为:
(1)按频次排定次序 通常,如果一个页面包含了越多的关键词,其搜索目标的相关性应该越好,这是非常合平常理的解决方案。
(2)按页面被访问度排序 在这种方法中,搜索引擎会记录它所搜索到的页面被访问的频率。人们访问较多的页面通常应该包含比较多的信息,或者有其他吸引入的长处。这种解决方案适合一般的搜索用户,而因为大部分的搜索引擎都不是专业性用户,所以这种方案也比较适合一般搜索引擎使用。
(3)二次检索 进一步净化(比flne)结果,按照一定的条件对搜索结果进行优化,可以再选择类别、相关词进行二次搜索等。
由于目前的搜索引擎还不具备智能,除非知道要查找的文档的标题,否则排列第一的结果未必是“最好”的结果。所以有些文档尽管相关程度高,但并不一定是用户最需要的文档。
搜索引擎技术的行业应用:
搜索引擎的行业应用一般指类似于千瓦通信提供的多种搜索引擎行业与产品应用模式,大体上分为如下几种形式:
1、 政府机关行业应用
n 实时跟踪、采集与业务工作相关的信息来源。
n 全面满足内部工作人员对互联网信息的全局观测需求。
n 及时解决政务外网、政务内网的信息源问题,实现动态发布。
n 快速解决政府主网站对各地级子网站的信息获取需求。
n 全面整合信息,实现政府内部跨地区、跨部门的信息资源共享与有效沟通。
n 节约信息采集的人力、物力、时间,提高办公效率。
2、企业行业应用
n 实时准确地监控、追踪竞争对手动态,是企业获取竞争情报的利器。
n 及时获取竞争对手的公开信息以便研究同行业的发展与市场需求。
n 为企业决策部门和管理层提供便捷、多途径的企业战略决策工具。
n 大幅度地提高企业获取、利用情报的效率,节省情报信息收集、存储、挖掘的相关费用,是提高企业核心竞争力的关键。
n 提高企业整体分析研究能力、市场快速反应能力,建立起以知识管理为核心的竞争情报数据仓库,是提高企业核心竞争力的神经中枢。
3、新闻媒体行业应用
n 快速准确地自动跟踪、采集数千家网络媒体信息,扩大新闻线索,提高采集速度。
n 支持每天对数万条新闻进行有效抓取。监控范围的深度、广度可以自行设定。
n 支持对所需内容智能提取、审核。
n 实现互联网信息内容采集、浏览、编辑、管理、发布的一体化。
4、 行业网站应用
n 实时跟踪、采集与网站相关的信息来源。
n 及时跟踪行业的信息来源网站,自动,快速更新网站信息。动态更新信息。
n 实现互联网信息内容采集、浏览、编辑、管理、发布的一体化。
n 针对商务网站提出商务管理模式,大大提高行业网站的商务应用需求。
n 针对资讯网站分类目录生成,提出用户生成网站分类结构。并可以实时增加与更新分类结构。不受级数限制。从而大大利高行业的应用性。
n 提供搜索引擎SEO优化专业服务,快速提高行业网站的推广。
n 提供与CCDC呼叫搜索引擎的广告合作。建立行业网站联盟,提高行业网站知名度。
5) 网络信息监察与监控
n 网络舆情系统。如“千瓦通信-网络舆情雷达监测系统”
n 网站信息与内容监察与监控系统,如“千瓦通信-网站信息与内容监测与监察系统(站内神探)”
随着因特网的迅猛发展、WEB信息的增加,用户要在信息海洋里查找信息,就象大海捞
针一样,搜索引擎技术恰好解决了这一难题(它可以为用户提供信息检索服务)。目前,
搜索引擎技术正成为计算机工业界和学术界争相研究、开发的对象。
搜索引擎(Search Engine)是随着WEB信息的迅速增加,从1995年开始逐渐发展起来
的技术。据发表在《科学》杂志1999年7月的文章《WEB信息的可访问性》估计,全球目前
的网页超过8亿,有效数据超过9T,并且仍以每4个月翻一番的速度增长。用户要在如此浩
瀚的信息海洋里寻找信息,必然会"大海捞针"无功而返。搜索引擎正是为了解决这个"迷航
"问题而出现的技术。搜索引擎以一定的策略在互联网中搜集、发现信息,对信息进行理解
、提取、组织和处理,并为用户提供检索服务,从而起到信息导航的目的。搜索引擎提供
的导航服务已经成为互联网上非常重要的网络服务,搜索引擎站点也被美誉为"网络门户"
。搜索引擎技术因而成为计算机工业界和学术界争相研究、开发的对象。本文旨在对搜索
引擎的关键技术进行简单的介绍,以起到抛砖引玉的作用。

分 类

按照信息搜集方法和服务提供方式的不同,搜索引擎系统可以分为三大类:
1.目录式搜索引擎:以人工方式或半自动方式搜集信息,由编辑员查看信息之后,人
工形成信息摘要,并将信息置于事先确定的分类框架中。信息大多面向网站,提供目录浏
览服务和直接检索服务。该类搜索引擎因为加入了人的智能,所以信息准确、导航质量高
,缺点是需要人工介入、维护量大、信息量少、信息更新不及时。这类搜索引擎的代表是
:Yahoo、LookSmart、Open Directory、Go Guide等。
2.机器人搜索引擎:由一个称为蜘蛛(Spider)的机器人程序以某种策略自动地在互
联网中搜集和发现信息,由索引器为搜集到的信息建立索引,由检索器根据用户的查询输
入检索索引库,并将查询结果返回给用户。服务方式是面向网页的全文检索服务。该类搜
索引擎的优点是信息量大、更新及时、毋需人工干预,缺点是返回信息过多,有很多无关
信息,用户必须从结果中进行筛选。这类搜索引擎的代表是:AltaVista、Northern Ligh
t、Excite、Infoseek、Inktomi、FAST、Lycos、Google;国内代表为:"天网"、悠游、O
penFind等。
3.元搜索引擎:这类搜索引擎没有自己的数据,而是将用户的查询请求同时向多个搜
索引擎递交,将返回的结果进行重复排除、重新排序等处理后,作为自己的结果返回给用
户。服务方式为面向网页的全文检索。这类搜索引擎的优点是返回结果的信息量更大、更
全,缺点是不能够充分使用所使用搜索引擎的功能,用户需要做更多的筛选。这类搜索引
擎的代表是WebCrawler、InfoMarket等。

性 能 指 标
我们可以将WEB信息的搜索看作一个信息检索问题,即在由WEB网页组成的文档库中检索
出与用户查询相关的文档。所以我们可以用衡量传统信息检索系统的性能参数-召回率(R
ecall)和精度(Pricision)衡量一个搜索引擎的性能。
召回率是检索出的相关文档数和文档库中所有的相关文档数的比率,衡量的是检索系
统(搜索引擎)的查全率;精度是检索出的相关文档数与检索出的文档总数的比率,衡量
的是检索系统(搜索引擎)的查准率。对于一个检索系统来讲,召回率和精度不可能两全
其美:召回率高时,精度低,精度高时,召回率低。所以常常用11种召回率下11种精度的
平均值(即11点平均精度)来衡量一个检索系统的精度。对于搜索引擎系统来讲,因为没
有一个搜索引擎系统能够搜集到所有的WEB网页,所以召回率很难计算。目前的搜索引擎系
统都非常关心精度。
影响一个搜索引擎系统的性能有很多因素,最主要的是信息检索模型,包括文档和查询
的表示方法、评价文档和用户查询相关性的匹配策略、查询结果的排序方法和用户进行相
关度反馈的机制。

主 要 技 术
一个搜索引擎由搜索器、索引器、检索器和用户接口等四个部分组成。
1.搜索器
搜索器的功能是在互联网中漫游,发现和搜集信息。它常常是一个计算机程序,日夜
不停地运行。它要尽可能多、尽可能快地搜集各种类型的新信息,同时因为互联网上的信
息更新很快,所以还要定期更新已经搜集过的旧信息,以避免死连接和无效连接。目前有
两种搜集信息的策略:
● 从一个起始URL集合开始,顺着这些URL中的超链(Hyperlink),以宽度优先、深
度优先或启发式方式循环地在互联网中发现信息。这些起始URL可以是任意的URL,但常常
是一些非常流行、包含很多链接的站点(如Yahoo!)。
● 将Web空间按照域名、IP地址或国家域名划分,每个搜索器负责一个子空间的穷尽
搜索。 搜索器搜集的信息类型多种多样,包括HTML、XML、Newsgroup文章、FTP文件、
字处理文档、多媒体信息。 搜索器的实现常常用分布式、并行计算技术,以提高信息
发现和更新的速度。商业搜索引擎的信息发现可以达到每天几百万网页。
2.索引器
索引器的功能是理解搜索器所搜索的信息,从中抽取出索引项,用于表示文档以及生
成文档库的索引表。
索引项有客观索引项和内容索引项两种:客观项与文档的语意内容无关,如作者名、
URL、更新时间、编码、长度、链接流行度(Link Popularity)等等;内容索引项是用来
反映文档内容的,如关键词及其权重、短语、单字等等。内容索引项可以分为单索引项和
多索引项(或称短语索引项)两种。单索引项对于英文来讲是英语单词,比较容易提取,
因为单词之间有天然的分隔符(空格);对于中文等连续书写的语言,必须进行词语的切
分。 在搜索引擎中,一般要给单索引项赋与一个权值,以表示该索引项对文档的区分
度,同时用来计算查询结果的相关度。使用的方法一般有统计法、信息论法和概率法。短
语索引项的提取方法有统计法、概率法和语言学法。
索引表一般使用某种形式的倒排表(Inversion List),即由索引项查找相应的文档
。索引表也可能要记录索引项在文档中出现的位置,以便检索器计算索引项之间的相邻或
接近关系(proximity)。
索引器可以使用集中式索引算法或分布式索引算法。当数据量很大时,必须实现即时
索引(Instant Indexing),否则不能够跟上信息量急剧增加的速度。索引算法对索引器
的性能(如大规模峰值查询时的响应速度)有很大的影响。一个搜索引擎的有效性在很大
程度上取决于索引的质量。
3.检索器 检索器的功能是根据用户的查询在索引库中快速检出文档,进行文档与
查询的相关度评价,对将要输出的结果进行排序,并实现某种用户相关性反馈机制。
检索器常用的信息检索模型有集合理论模型、代数模型、概率模型和混合模型四种。
4.用户接口
用户接口的作用是输入用户查询、显示查询结果、提供用户相关性反馈机制。主要的
目的是方便用户使用搜索引擎,高效率、多方式地从搜索引擎中得到有效、及时的信息。
用户接口的设计和实现使用人机交互的理论和方法,以充分适应人类的思维习惯。
用户输入接口可以分为简单接口和复杂接口两种。
简单接口只提供用户输入查询串的文本框;复杂接口可以让用户对查询进行限制,如
逻辑运算(与、或、非;+、-)、相近关系(相邻、NEAR)、域名范围(如.e、.com)
、出现位置(如标题、内容)、信息时间、长度等等。目前一些公司和机构正在考虑制定
查询选项的标准。

未 来 动 向
搜索引擎已成为一个新的研究、开发领域。因为它要用到信息检索、人工智能、计算
机网络、分布式处理、数据库、数据挖掘、数字图书馆、自然语言处理等多领域的理论和
技术,所以具有综合性和挑战性。又由于搜索引擎有大量的用户,有很好的经济价值,所
以引起了世界各国计算机科学界和信息产业界的高度关注,目前的研究、开发十分活跃,
并出现了很多值得注意的动向。
1.十分注意提高信息查询结果的精度,提高检索的有效性 用户在搜索引擎上进行
信息查询时,并不十分关注返回结果的多少,而是看结果是否和自己的需求吻合。对于一
个查询,传统的搜索引擎动辄返回几十万、几百万篇文档,用户不得不在结果中筛选。解
决查询结果过多的现象目前出现了几种方法:一是通过各种方法获得用户没有在查询语句
中表达出来的真正用途,包括使用智能代理跟踪用户检索行为,分析用户模型;使用相关
度反馈机制,使用户告诉搜索引擎哪些文档和自己的需求相关(及其相关的程度),哪些
不相关,通过多次交互逐步求精。二是用正文分类(Text Categorization)技术将结果分
类,使用可视化技术显示分类结构,用户可以只浏览自己感兴趣的类别。三是进行站点类
聚或内容类聚,减少信息的总量。
2.基于智能代理的信息过滤和个性化服务
信息智能代理是另外一种利用互联网信息的机制。它使用自动获得的领域模型(如We
b知识、信息处理、与用户兴趣相关的信息资源、领域组织结构)、用户模型(如用户背景
、兴趣、行为、风格)知识进行信息搜集、索引、过滤(包括兴趣过滤和不良信息过滤)
,并自动地将用户感兴趣的、对用户有用的信息提交给用户。智能代理具有不断学习、适
应信息和用户兴趣动态变化的能力,从而提供个性化的服务。智能代理可以在用户端进行
,也可以在服务器端运行。
3.采用分布式体系结构提高系统规模和性能
搜索引擎的实现可以采用集中式体系结构和分布式体系结构,两种方法各有千秋。但
当系统规模到达一定程度(如网页数达到亿级)时,必然要采用某种分布式方法,以提高
系统性能。搜索引擎的各个组成部分,除了用户接口之外,都可以进行分布:搜索器可以
在多台机器上相互合作、相互分工进行信息发现,以提高信息发现和更新速度;索引器可
以将索引分布在不同的机器上,以减小索引对机器的要求;检索器可以在不同的机器上.

❸ 请问什么是搜索算法

搜索算法是利用计算机的高性能来有目的的穷举一个问题的部分或所有的可能情况,从而求出问题的解
的一种方法。搜索过程实际上是根据初始条件和扩展规则构造一棵解答树并寻找符合目标状态的节点的过程。
所有的搜索算法从其最终的算法实现上来看,都可以划分成两个部分——控制结构和产生系统,而所有的算
法的优化和改进主要都是通过修改其控制结构来完成的。

❹ 实现二分搜索算法,并分析其时间复杂度

对于这样一个谓词f(),满足性质:若f(a)=true,则对于任意定义域内的b>a,f(b)=true.
l与r为值域
int work ( int begin , int end ) {
while ( end - begin != 1 ) {
const int middle = ( begin + end ) / 2 ;
if ( f ( middle ) ) end = middle ;
else begin = middle ;
}
return begin ;
}
返回的是最大的x使f(x)为否

❺ 二分搜索算法的实现

二分搜索的时候,是要慢慢缩小搜索范围的。比如一共有10个,那么middle是5,下一层搜索的范围应该是1-4和6-10。你的函数里没有这个功能。搜索函数至少应该是int BinarySearch(Type a[], const Type& x,int left, int right);终止条件就是if(left > right) 你定义y的时候是在main函数里,所以BinarySearch里面不能直接用y,解决方式是在外部定义一个全局的y变量,或者把y变量传到函数里。

❻ C语言递归函数如何实现二分搜索算法

折半查找法也称为二分查找法,它充分利用了元素间的次序关系,采用分治策略,可在最坏的情况下用O(log n)完成搜索任务。它的基本思想是,已知一个有n个元素的有序序列, 将n个元素分成个数大致相同的两半,取a[n/2]与欲查找的x作比较,如果x=a[n/2]则找到x,算法终止。如果x<a[n/2],则我们只要在数组a的左半部继续搜索x(这里假设数组元素呈升序排列)。如果x>a[n/2],则我们只要在数组a的右半部继续搜索x, 直到找到x或者是没有找到!

如果是常规的方法的话那么我们可以通过循环的方式, 按照上面说的算法, 找到则退出循环, 否则继续循环直到左下标位置小于或者等于右下标的位置.

按兄弟你的意思是要用递归方法进行搜索, 那么大概还是上面的算法, 只是把循环的方式改成递归方式: 如果没找到,则确定新的搜索范围, 即左右下标新位置, 然后把新的参数传给函数继续调用函数进行递归搜索!!

递归方式实现详细代码如下:

#include <stdio.h>

#define ARRAY_SIZE 10
#define NOT_FOUND -1

int BinarySearch(int array[], int left, int right, int NumToSearch)
{
int mid = (left + right) / 2;

if (left <= right)
{
if (NumToSearch == array[mid])
{
return mid;
}
else if (NumToSearch < array[mid])
{
right = mid - 1;
return BinarySearch(array, left, right, NumToSearch);
}
else
{
left = mid + 1;
return BinarySearch(array, left, right, NumToSearch);
}
}

return NOT_FOUND;
}

int main()
{
int a[ARRAY_SIZE] = {2, 5, 6, 7, 13, 20, 22, 27, 112, 222};//假设一个已知的有序且是升序数列
int result = 0;//查找的结果
int x = 13;//假设我们要查找的数是13
int left = 0;//序列开始下标
int right = ARRAY_SIZE - 1;//序列结尾下标

result = BinarySearch(a, left, right, x);
if (result == NOT_FOUND)
{
printf("Not Found!\n");
}
else
{
printf("Found %d in array a, it is a[%d]\n", x, result);
}

return 0;

}

希望对兄弟你有帮助!

❼ A*搜寻算法的代码实现(C语言实现)

用C语言实现A*最短路径搜索算法,作者 Tittup frog(跳跳蛙)。 #include<stdio.h>#include<math.h>#defineMaxLength100 //用于优先队列(Open表)的数组#defineHeight15 //地图高度#defineWidth20 //地图宽度#defineReachable0 //可以到达的结点#defineBar1 //障碍物#definePass2 //需要走的步数#defineSource3 //起点#defineDestination4 //终点#defineSequential0 //顺序遍历#defineNoSolution2 //无解决方案#defineInfinity0xfffffff#defineEast(1<<0)#defineSouth_East(1<<1)#defineSouth(1<<2)#defineSouth_West(1<<3)#defineWest(1<<4)#defineNorth_West(1<<5)#defineNorth(1<<6)#defineNorth_East(1<<7)typedefstruct{ signedcharx,y;}Point;constPointdir[8]={ {0,1},//East {1,1},//South_East {1,0},//South {1,-1},//South_West {0,-1},//West {-1,-1},//North_West {-1,0},//North {-1,1}//North_East};unsignedcharwithin(intx,inty){ return(x>=0&&y>=0 &&x<Height&&y<Width);}typedefstruct{ intx,y; unsignedcharreachable,sur,value;}MapNode;typedefstructClose{ MapNode*cur; charvis; structClose*from; floatF,G; intH;}Close;typedefstruct//优先队列(Open表){ intlength; //当前队列的长度 Close*Array[MaxLength]; //评价结点的指针}Open;staticMapNodegraph[Height][Width];staticintsrcX,srcY,dstX,dstY; //起始点、终点staticCloseclose[Height][Width];//优先队列基本操作voidinitOpen(Open*q) //优先队列初始化{ q->length=0; //队内元素数初始为0}voidpush(Open*q,Closecls[Height][Width],intx,inty,floatg){ //向优先队列(Open表)中添加元素 Close*t; inti,mintag; cls[x][y].G=g; //所添加节点的坐标 cls[x][y].F=cls[x][y].G+cls[x][y].H; q->Array[q->length++]=&(cls[x][y]); mintag=q->length-1; for(i=0;i<q->length-1;i++) { if(q->Array[i]->F<q->Array[mintag]->F) { mintag=i; } } t=q->Array[q->length-1]; q->Array[q->length-1]=q->Array[mintag]; q->Array[mintag]=t; //将评价函数值最小节点置于队头}Close*shift(Open*q){ returnq->Array[--q->length];}//地图初始化操作voidinitClose(Closecls[Height][Width],intsx,intsy,intdx,intdy){ //地图Close表初始化配置 inti,j; for(i=0;i<Height;i++) { for(j=0;j<Width;j++) { cls[i][j].cur=&graph[i][j]; //Close表所指节点 cls[i][j].vis=!graph[i][j].reachable; //是否被访问 cls[i][j].from=NULL; //所来节点 cls[i][j].G=cls[i][j].F=0; cls[i][j].H=abs(dx-i)+abs(dy-j); //评价函数值 } } cls[sx][sy].F=cls[sx][sy].H; //起始点评价初始值 // cls[sy][sy].G=0; //移步花费代价值 cls[dx][dy].G=Infinity;}voidinitGraph(constintmap[Height][Width],intsx,intsy,intdx,intdy){ //地图发生变化时重新构造地 inti,j; srcX=sx; //起点X坐标 srcY=sy; //起点Y坐标 dstX=dx; //终点X坐标 dstY=dy; //终点Y坐标 for(i=0;i<Height;i++) { for(j=0;j<Width;j++) { graph[i][j].x=i;//地图坐标X graph[i][j].y=j;//地图坐标Y graph[i][j].value=map[i][j]; graph[i][j].reachable=(graph[i][j].value==Reachable); //节点可到达性 graph[i][j].sur=0;//邻接节点个数 if(!graph[i][j].reachable) { continue; } if(j>0) { if(graph[i][j-1].reachable) //left节点可以到达 { graph[i][j].sur|=West; graph[i][j-1].sur|=East; } if(i>0) { if(graph[i-1][j-1].reachable &&graph[i-1][j].reachable &&graph[i][j-1].reachable) //up-left节点可以到达 { graph[i][j].sur|=North_West; graph[i-1][j-1].sur|=South_East; } } } if(i>0) { if(graph[i-1][j].reachable) //up节点可以到达 { graph[i][j].sur|=North; graph[i-1][j].sur|=South; } if(j<Width-1) { if(graph[i-1][j+1].reachable &&graph[i-1][j].reachable &&map[i][j+1]==Reachable)//up-right节点可以到达 { graph[i][j].sur|=North_East; graph[i-1][j+1].sur|=South_West; } } } } }}intbfs(){ inttimes=0; inti,curX,curY,surX,surY; unsignedcharf=0,r=1; Close*p; Close*q[MaxLength]={&close[srcX][srcY]}; initClose(close,srcX,srcY,dstX,dstY); close[srcX][srcY].vis=1; while(r!=f) { p=q[f]; f=(f+1)%MaxLength; curX=p->cur->x; curY=p->cur->y; for(i=0;i<8;i++) { if(!(p->cur->sur&(1<<i))) { continue; } surX=curX+dir[i].x; surY=curY+dir[i].y; if(!close[surX][surY].vis) { close[surX][surY].from=p; close[surX][surY].vis=1; close[surX][surY].G=p->G+1; q[r]=&close[surX][surY]; r=(r+1)%MaxLength; } } times++; } returntimes;}intastar(){ //A*算法遍历 //inttimes=0; inti,curX,curY,surX,surY; floatsurG; Openq;//Open表 Close*p; initOpen(&q); initClose(close,srcX,srcY,dstX,dstY); close[srcX][srcY].vis=1; push(&q,close,srcX,srcY,0); while(q.length) { //times++; p=shift(&q); curX=p->cur->x; curY=p->cur->y; if(!p->H) { returnSequential; } for(i=0;i<8;i++) { if(!(p->cur->sur&(1<<i))) { continue; } surX=curX+dir[i].x; surY=curY+dir[i].y; if(!close[surX][surY].vis) { close[surX][surY].vis=1; close[surX][surY].from=p; surG=p->G+sqrt((curX-surX)*(curX-surX)+(curY-surY)*(curY-surY)); push(&q,close,surX,surY,surG); } } } //printf("times:%d ",times); returnNoSolution;//无结果}constintmap[Height][Width]={ {0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,1,1}, {0,0,1,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1}, {0,0,0,0,0,0,1,0,0,0,0,0,0,1,1,0,0,0,0,1}, {0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,1}, {0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,1,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,1,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0}, {0,0,0,0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0}, {0,1,0,0,0,0,1,0,0,0,0,0,0,1,0,1,0,0,0,1}, {0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0}};constcharSymbol[5][3]={"□","▓","▽","☆","◎"};voidprintMap(){ inti,j; for(i=0;i<Height;i++) { for(j=0;j<Width;j++) { printf("%s",Symbol[graph[i][j].value]); } puts(""); } puts("");}Close*getShortest(){ //获取最短路径 intresult=astar(); Close*p,*t,*q=NULL; switch(result) { caseSequential: //顺序最近 p=&(close[dstX][dstY]); while(p) //转置路径 { t=p->from; p->from=q; q=p; p=t; } close[srcX][srcY].from=q->from; return&(close[srcX][srcY]); caseNoSolution: returnNULL; } returnNULL;}staticClose*start;staticintshortestep;intprintShortest(){ Close*p; intstep=0; p=getShortest(); start=p; if(!p) { return0; } else { while(p->from) { graph[p->cur->x][p->cur->y].value=Pass; printf("(%d,%d)→ ",p->cur->x,p->cur->y); p=p->from; step++; } printf("(%d,%d) ",p->cur->x,p->cur->y); graph[srcX][srcY].value=Source; graph[dstX][dstY].value=Destination; returnstep; }}voidclearMap(){ //ClearMapMarksofSteps Close*p=start; while(p) { graph[p->cur->x][p->cur->y].value=Reachable; p=p->from; } graph[srcX][srcY].value=map[srcX][srcY]; graph[dstX][dstY].value=map[dstX][dstY];}voidprintDepth(){ inti,j; for(i=0;i<Height;i++) { for(j=0;j<Width;j++) { if(map[i][j]) { printf("%s",Symbol[graph[i][j].value]); } else { printf("%2.0lf",close[i][j].G); } } puts(""); } puts("");}voidprintSur(){ inti,j; for(i=0;i<Height;i++) { for(j=0;j<Width;j++) { printf("%02x",graph[i][j].sur); } puts(""); } puts("");}voidprintH(){ inti,j; for(i=0;i<Height;i++) { for(j=0;j<Width;j++) { printf("%02d",close[i][j].H); } puts(""); } puts("");}intmain(intargc,constchar**argv){ initGraph(map,0,0,0,0); printMap(); while(scanf("%d%d%d%d",&srcX,&srcY,&dstX,&dstY)!=EOF) { if(within(srcX,srcY)&&within(dstX,dstY)) { if(shortestep=printShortest()) { printf("从(%d,%d)到(%d,%d)的最短步数是:%d ", srcX,srcY,dstX,dstY,shortestep); printMap(); clearMap(); bfs(); //printDepth(); puts((shortestep==close[dstX][dstY].G)?"正确":"错误"); clearMap(); } else { printf("从(%d,%d)不可到达(%d,%d) ", srcX,srcY,dstX,dstY); } } else { puts("输入错误!"); } } return(0);}

❽ 图的深度优先搜索和广度优先搜索算法的实现

//图的遍历算法程序

//图的遍历是指按某条搜索路径访问图中每个结点,使得每个结点均被访问一次,而且仅被访问一次。图的遍历有深度遍历算法和广度遍历算法,程序如下:
#include <iostream>
//#include <malloc.h>
#define INFINITY 32767
#define MAX_VEX 20 //最大顶点个数
#define QUEUE_SIZE (MAX_VEX+1) //队列长度
using namespace std;
bool *visited; //访问标志数组
//图的邻接矩阵存储结构
typedef struct{
char *vexs; //顶点向量
int arcs[MAX_VEX][MAX_VEX]; //邻接矩阵
int vexnum,arcnum; //图的当前顶点数和弧数
}Graph;
//队列类
class Queue{
public:
void InitQueue(){
base=(int *)malloc(QUEUE_SIZE*sizeof(int));
front=rear=0;
}
void EnQueue(int e){
base[rear]=e;
rear=(rear+1)%QUEUE_SIZE;
}
void DeQueue(int &e){
e=base[front];
front=(front+1)%QUEUE_SIZE;
}
public:
int *base;
int front;
int rear;
};
//图G中查找元素c的位置
int Locate(Graph G,char c){
for(int i=0;i<G.vexnum;i++)
if(G.vexs[i]==c) return i;
return -1;
}
//创建无向网
void CreateUDN(Graph &G){
int i,j,w,s1,s2;
char a,b,temp;
printf("输入顶点数和弧数:");
scanf("%d%d",&G.vexnum,&G.arcnum);
temp=getchar(); //接收回车
G.vexs=(char *)malloc(G.vexnum*sizeof(char)); //分配顶点数目
printf("输入%d个顶点.\n",G.vexnum);
for(i=0;i<G.vexnum;i++){ //初始化顶点
printf("输入顶点%d:",i);
scanf("%c",&G.vexs[i]);
temp=getchar(); //接收回车
}
for(i=0;i<G.vexnum;i++) //初始化邻接矩阵
for(j=0;j<G.vexnum;j++)
G.arcs[i][j]=INFINITY;
printf("输入%d条弧.\n",G.arcnum);
for(i=0;i<G.arcnum;i++){ //初始化弧
printf("输入弧%d:",i);
scanf("%c %c %d",&a,&b,&w); //输入一条边依附的顶点和权值
temp=getchar(); //接收回车
s1=Locate(G,a);
s2=Locate(G,b);
G.arcs[s1][s2]=G.arcs[s2][s1]=w;
}
}
//图G中顶点k的第一个邻接顶点
int FirstVex(Graph G,int k){
if(k>=0 && k<G.vexnum){ //k合理
for(int i=0;i<G.vexnum;i++)
if(G.arcs[k][i]!=INFINITY) return i;
}
return -1;
}
//图G中顶点i的第j个邻接顶点的下一个邻接顶点
int NextVex(Graph G,int i,int j){
if(i>=0 && i<G.vexnum && j>=0 && j<G.vexnum){ //i,j合理
for(int k=j+1;k<G.vexnum;k++)
if(G.arcs[i][k]!=INFINITY) return k;
}
return -1;
}
//深度优先遍历
void DFS(Graph G,int k){
int i;
if(k==-1){ //第一次执行DFS时,k为-1
for(i=0;i<G.vexnum;i++)
if(!visited[i]) DFS(G,i); //对尚未访问的顶点调用DFS
}
else{
visited[k]=true;
printf("%c ",G.vexs[k]); //访问第k个顶点
for(i=FirstVex(G,k);i>=0;i=NextVex(G,k,i))
if(!visited[i]) DFS(G,i); //对k的尚未访问的邻接顶点i递归调用DFS
}
}
//广度优先遍历
void BFS(Graph G){
int k;
Queue Q; //辅助队列Q
Q.InitQueue();
for(int i=0;i<G.vexnum;i++)
if(!visited[i]){ //i尚未访问
visited[i]=true;
printf("%c ",G.vexs[i]);
Q.EnQueue(i); //i入列
while(Q.front!=Q.rear){
Q.DeQueue(k); //队头元素出列并置为k
for(int w=FirstVex(G,k);w>=0;w=NextVex(G,k,w))
if(!visited[w]){ //w为k的尚未访问的邻接顶点
visited[w]=true;
printf("%c ",G.vexs[w]);
Q.EnQueue(w);
}
}
}
}

//主函数
void main(){
int i;
Graph G;
CreateUDN(G);
visited=(bool *)malloc(G.vexnum*sizeof(bool));
printf("\n广度优先遍历: ");
for(i=0;i<G.vexnum;i++)
visited[i]=false;
DFS(G,-1);
printf("\n深度优先遍历: ");
for(i=0;i<G.vexnum;i++)
visited[i]=false;
BFS(G);
printf("\n程序结束.\n");
}
输出结果为(红色为键盘输入的数据,权值都置为1):
输入顶点数和弧数:8 9
输入8个顶点.
输入顶点0:a
输入顶点1:b
输入顶点2:c
输入顶点3:d
输入顶点4:e
输入顶点5:f
输入顶点6:g
输入顶点7:h
输入9条弧.
输入弧0:a b 1
输入弧1:b d 1
输入弧2:b e 1
输入弧3:d h 1
输入弧4:e h 1
输入弧5:a c 1
输入弧6:c f 1
输入弧7:c g 1
输入弧8:f g 1
广度优先遍历: a b d h e c f g
深度优先遍历: a b c d e f g h
程序结束.

已经在vc++内运行通过,这个程序已经达到要求了呀~

❾ 详细介绍广度优先搜索的实现,原理,c++程序

宽度优先搜索算法(又称广度优先搜索)是最简便的图的搜索算法之一,这一算法也是很多重要的图的算法的原型。Dijkstra单源最短路径算法和Prim最小生成树算法都采用了和宽度优先搜索类似的思想。其别名又叫BFS,属于一种盲目搜寻法,目的是系统地展开并检查图中的所有节点,以找寻结果。换句话说,它并不考虑结果的可能位址,彻底地搜索整张图,直到找到结果为止。

已知图G=(V,E)和一个源顶点s,宽度优先搜索以一种系统的方式探寻G的边,从而“发现”s所能到达的所有顶点,并计算s到所有这些顶点的距离(最少边数),该算法同时能生成一棵根为s且包括所有可达顶点的宽度优先树。对从s可达的任意顶点v,宽度优先树中从s到v的路径对应于图G中从s到v的最短路径,即包含最小边数的路径。该算法对有向图和无向图同样适用。
之所以称之为宽度优先算法,是因为算法自始至终一直通过已找到和未找到顶点之间的边界向外扩展,就是说,算法首先搜索和s距离为k的所有顶点,然后再去搜索和S距离为k+l的其他顶点。
为了保持搜索的轨迹,宽度优先搜索为每个顶点着色:白色、灰色或黑色。算法开始前所有顶点都是白色,随着搜索的进行,各顶点会逐渐变成灰色,然后成为黑色。在搜索中第一次碰到一顶点时,我们说该顶点被发现,此时该顶点变为非白色顶点。因此,灰色和黑色顶点都已被发现,但是,宽度优先搜索算法对它们加以区分以保证搜索以宽度优先的方式执行。若(u,v)∈E且顶点u为黑色,那么顶点v要么是灰色,要么是黑色,就是说,所有和黑色顶点邻接的顶点都已被发现。灰色顶点可以与一些白色顶点相邻接,它们代表着已找到和未找到顶点之间的边界。
在宽度优先搜索过程中建立了一棵宽度优先树,起始时只包含根节点,即源顶点s.在扫描已发现顶点u的邻接表的过程中每发现一个白色顶点v,该顶点v及边(u,v)就被添加到树中。在宽度优先树中,我们称结点u 是结点v的先辈或父母结点。因为一个结点至多只能被发现一次,因此它最多只能有--个父母结点。相对根结点来说祖先和后裔关系的定义和通常一样:如果u处于树中从根s到结点v的路径中,那么u称为v的祖先,v是u的后裔。

❿ 用c++语言实现二分搜索算法

这个就是二分法排序函数的源代码 传入参数是数组a和数组的大小n
template <class T>
void BinSort( T a[], int n ) {
int low,high,mid;
for (int i=1; i<n; i++) {
T t=a[i];
low=0; high=i-1;
while (low<=high) {
mid=(low+high)/2;
if (a[mid]>t) high=mid-1;
else low=mid+1;
}
for (int j=i-1; j>=high+1; j--) a[j+1]=a[j];
a[high+1]=t;
}
}

热点内容
mac访问windows共享 发布:2024-10-01 23:31:58 浏览:642
java培训要学什么 发布:2024-10-01 23:15:54 浏览:537
c语言编程学习宝典 发布:2024-10-01 22:35:08 浏览:344
无法打开脚本文件 发布:2024-10-01 22:14:51 浏览:108
javaxml格式字符串格式 发布:2024-10-01 21:54:03 浏览:654
为什么安卓玩游戏都选骁龙 发布:2024-10-01 21:48:07 浏览:376
如何避免服务器暴露ip 发布:2024-10-01 21:38:24 浏览:220
pythonrequestjson 发布:2024-10-01 21:37:37 浏览:856
珠海java 发布:2024-10-01 21:07:29 浏览:823
服务器剩余维护是什么 发布:2024-10-01 21:03:46 浏览:546