搜索算法

合集下载

数据结构最基础的十大算法

数据结构最基础的十大算法

数据结构最基础的十大算法数据结构是计算机科学中的重要分支,它研究如何组织和存储数据以便于访问和修改。

在数据结构中,算法是解决问题的关键。

下面将介绍数据结构中最基础的十大算法。

1. 线性搜索算法线性搜索算法是最简单的算法之一,它的作用是在一个列表中查找一个特定的元素。

该算法的时间复杂度为O(n),其中n是列表中元素的数量。

2. 二分搜索算法二分搜索算法是一种更高效的搜索算法,它的时间复杂度为O(log n)。

该算法要求列表必须是有序的,它通过将列表分成两半来查找元素,直到找到目标元素为止。

3. 冒泡排序算法冒泡排序算法是一种简单的排序算法,它的时间复杂度为O(n^2)。

该算法通过比较相邻的元素并交换它们的位置来排序列表。

4. 快速排序算法快速排序算法是一种更高效的排序算法,它的时间复杂度为O(nlog n)。

该算法通过选择一个基准元素并将列表分成两部分来排序列表。

5. 插入排序算法插入排序算法是一种简单的排序算法,它的时间复杂度为O(n^2)。

该算法通过将每个元素插入到已排序的列表中来排序列表。

6. 选择排序算法选择排序算法是一种简单的排序算法,它的时间复杂度为O(n^2)。

该算法通过选择最小的元素并将其放在列表的开头来排序列表。

7. 堆排序算法堆排序算法是一种更高效的排序算法,它的时间复杂度为O(n log n)。

该算法通过将列表转换为堆并进行排序来排序列表。

8. 归并排序算法归并排序算法是一种更高效的排序算法,它的时间复杂度为O(n log n)。

该算法通过将列表分成两部分并将它们合并来排序列表。

9. 哈希表算法哈希表算法是一种高效的数据结构,它的时间复杂度为O(1)。

该算法通过将键映射到哈希表中的位置来存储和访问值。

10. 树算法树算法是一种重要的数据结构,它的时间复杂度取决于树的深度。

树算法包括二叉树、AVL树、红黑树等。

以上是数据结构中最基础的十大算法,它们在计算机科学中有着广泛的应用。

(完整版)《搜索算法》知识点总结

(完整版)《搜索算法》知识点总结

(完整版)《搜索算法》知识点总结1. 搜索算法的概念搜索算法是计算机科学中的一类算法,用于在一个数据集合中查找指定的数据项。

搜索算法的目标是通过最少的计算操作来找到目标数据项,以提高效率。

2. 常见的搜索算法2.1 线性搜索线性搜索是最简单的搜索算法之一,它从数据集合的第一个元素开始逐个比较,直到找到目标数据项或者遍历整个数据集合。

线性搜索的时间复杂度为O(n),其中n为数据集合的大小。

2.2 二分搜索二分搜索是一种高效的搜索算法,它适用于有序的数据集合。

它将数据集合分为两部分,并与目标数据项进行比较,然后根据比较结果确定继续搜索的方向。

通过每次排除一半的数据,二分搜索的时间复杂度为O(log n),其中n为数据集合的大小。

2.3 哈希搜索哈希搜索通过将数据项映射到哈希表中的特定索引位置来进行搜索。

通过哈希函数,可以快速找到目标数据项所在的位置。

哈希搜索的时间复杂度为O(1),但需要额外的存储空间来存储哈希表。

2.4 深度优先搜索深度优先搜索是一种递归的搜索算法,它从起始点开始一直沿着一个路径搜索,直到找到目标数据项或者无法继续搜索。

如果搜索失败,则回溯到上一个节点,并探索其他路径。

深度优先搜索在有向图和无向图中均适用。

2.5 广度优先搜索广度优先搜索是一种逐层扩展的搜索算法,它从起始点开始,先访问所有直接相邻的节点,然后再访问相邻节点的邻居节点。

通过队列数据结构,广度优先搜索可以按层次进行遍历,直到找到目标数据项。

广度优先搜索适用于无权图和加权图。

3. 搜索算法的应用场景搜索算法在各种领域和实际问题中广泛应用,包括但不限于以下几个方面:- 文本搜索:在大规模的文本数据集中查找关键字或短语。

- 图像搜索:根据图像特征找到相似的图像。

- 数据库查询:根据指定条件查询数据库中的记录。

- 路径规划:在地图上找到最短路径或最优路径。

- 推荐系统:根据用户的兴趣和偏好推荐相关的内容。

- 人工智能:在机器研究和深度研究中的搜索空间优化等。

常用查找算法的分类与特点

常用查找算法的分类与特点

常用查找算法的分类与特点在计算机科学中,查找算法是一种用于在数据集合中查找特定元素的方法。

查找算法的效率和性能对于许多应用程序来说至关重要,因为它们直接影响到程序的运行速度和资源使用情况。

本文将介绍一些常见的查找算法,并分析它们的特点和适用场景。

一、顺序查找顺序查找是最简单的查找算法之一。

它的基本思想是从数据集合的开头开始,逐个元素进行比较,直到找到目标元素或者遍历完整个数据集合。

顺序查找的优点是实现简单,对于小型数据集合或者无序数据集合来说,是一种可行的选择。

它不需要对数据进行预处理,也不需要额外的存储空间来保存索引或其他辅助信息。

然而,顺序查找的缺点也很明显。

它的平均查找时间复杂度为O(n),其中 n 是数据集合的大小。

这意味着当数据集合规模较大时,查找效率会非常低。

例如,如果我们要在一个包含 10000 个元素的数组中查找一个特定元素,最坏情况下可能需要比较 10000 次才能找到目标元素。

二、二分查找二分查找是一种在有序数据集合中进行查找的高效算法。

它的基本思想是通过不断将数据集合分成两半,比较目标元素与中间元素的大小,然后确定目标元素可能存在的子集合,重复这个过程直到找到目标元素或者确定目标元素不存在。

二分查找的优点是查找效率高,时间复杂度为 O(log n)。

这使得它在处理大规模有序数据集合时表现出色。

但是,二分查找要求数据集合必须是有序的。

如果数据集合是无序的,需要先进行排序,这会增加额外的时间和空间开销。

此外,二分查找在处理动态数据集合(即经常需要插入和删除元素的数据集合)时不太方便,因为每次插入或删除元素都可能破坏数据的有序性,需要重新进行排序。

三、哈希查找哈希查找是一种通过哈希函数将元素映射到哈希表中的特定位置来实现快速查找的算法。

哈希函数的设计至关重要,一个好的哈希函数能够将元素均匀地分布在哈希表中,减少冲突的发生。

当发生冲突时,通常采用链地址法或开放地址法等解决冲突的策略。

算法_五大经典搜索算法

算法_五大经典搜索算法

算法_五⼤经典搜索算法顺序查找最简单的从头开始对⽐查找。

折半查找要求:有序数组思想:将n个元素分成⼤致相同的两半,取中值和值x⽐较,如果相等则找到,如果值x⼩于中值,则只在数组的左半部分继续搜索值x;如果值x⼤于中值,则只在数组右半部分继续搜索值x复杂度:最坏情况下需要O(logN)时间代码如下:int binarySearch(int arr[], int x, int len){int left = 0, right = len-1;while(left <= right){int mid = (left + right) / 2;if(x == arr[mid]){return mid;}if(x > arr[mid]){left = mid + 1;}else{right = mid -1;}}return -1;}哈希查找时间复杂度为O(1)索引查找⼆叉树⼆叉树的前序遍历、中序遍历、后序遍历测试代码如下:package com.tree;public class Tree{public static void preOrder(TreeNode node){if(node == null){return ;}System.out.print(node.getData());preOrder(node.getLeft());preOrder(node.getRight());}public static void midOrder(TreeNode node){if(node == null){return ;}preOrder(node.getLeft());System.out.print(node.getData());preOrder(node.getRight());}public static void postOrder(TreeNode node){if(node == null){return ;}preOrder(node.getLeft());preOrder(node.getRight());System.out.print(node.getData());}public static void main(String[] args){TreeNode root = new TreeNode("A");TreeNode nodeB = new TreeNode("B");TreeNode nodeC = new TreeNode("C");TreeNode nodeD = new TreeNode("D");TreeNode nodeE = new TreeNode("E");TreeNode nodeF = new TreeNode("F");root.setLeft(nodeB);root.setRight(nodeC);nodeB.setLeft(nodeD);nodeB.setRight(nodeE);nodeC.setLeft(nodeF);System.out.print("先序遍历");preOrder(root);System.out.print("中序遍历");midOrder(root);System.out.print("后序遍历");postOrder(root);}}程序运⾏及结果如下(修改了控制台字体使得中⽂乱码):。

常用查找算法及其实践应用

常用查找算法及其实践应用

常用查找算法及其实践应用查找算法是计算机科学中的一类基本算法,用于在一组数据中快速查找目标值。

本文将介绍常用的查找算法及其实践应用,并讨论它们的优缺点。

一、线性查找算法线性查找算法,也称作顺序查找算法,是最简单直接的查找算法之一。

它通过逐个比较数据元素,直到找到目标值或搜索整个数据集。

实践应用:线性查找算法适用于数据量较小且无序的情况。

例如,在一个未排序的数组中查找一个特定的值。

二、二分查找算法二分查找算法,也称作折半查找算法,是一种高效的查找算法。

它将目标值与数据集的中间值进行比较,根据比较结果将搜索范围缩小一半,以此类推,直到找到目标值或搜索范围为空。

实践应用:二分查找算法适用于已排序的数据集。

比如,在一个有序数组中查找一个特定的值。

三、哈希查找算法哈希查找算法通过哈希函数将数据映射到一个固定的位置,然后在该位置进行查找。

它的平均查找时间复杂度为O(1),具有高效的查找速度。

实践应用:哈希查找算法适用于查找大规模数据集中的特定值。

它常被用于数据库索引、缓存系统等。

四、二叉查找树算法二叉查找树算法,也称作二叉搜索树算法,是一种基于二叉树的查找算法。

它具有以下特点:左子树的所有节点小于根节点,右子树的所有节点大于根节点。

通过比较目标值与根节点的大小关系,可以快速缩小搜索范围。

实践应用:二叉查找树算法适用于频繁插入和删除操作的场景。

它常被用于实现字典、关联数组等数据结构。

五、平衡查找树算法平衡查找树算法,如红黑树、AVL树等,是对二叉查找树的改进。

它通过调整节点的颜色和旋转操作来保持树的平衡,以确保查找效率的稳定性。

实践应用:平衡查找树算法适用于高效地处理大规模数据集的查找、插入和删除操作。

它常被用于数据库索引、编译器等领域。

六、后缀树算法后缀树算法是一种用于字符串查找的数据结构。

它将目标字符串的所有后缀都表示为树的节点,通过遍历树来查找目标字符串的子串。

实践应用:后缀树算法适用于文本搜索、模式匹配等领域。

给定n个数找指定数的算法

给定n个数找指定数的算法

给定n个数找指定数的算法
在日常生活中,我们经常需要在一堆数字中找到指定的数字。

这个问题在计算机科学中也是非常常见的。

在本文中,我们将介绍几种常见的算法,以帮助我们在给定的n个数中找到指定的数字。

1. 线性搜索算法
线性搜索算法是最简单的算法之一。

它的思想是从第一个数字开始,逐个比较每个数字,直到找到指定的数字或者搜索完所有数字。

这个算法的时间复杂度是O(n),其中n是数字的数量。

2. 二分搜索算法
二分搜索算法是一种更高效的算法。

它的思想是将数字按照顺序排列,然后将指定数字与中间数字进行比较。

如果指定数字比中间数字小,则在左侧继续搜索;如果指定数字比中间数字大,则在右侧继续搜索。

这个算法的时间复杂度是O(log n),其中n是数字的数量。

3. 哈希表算法
哈希表算法是一种基于哈希函数的算法。

它的思想是将数字存储在哈希表中,其中哈希函数将数字映射到哈希表中的一个位置。

当需要查找指定数字时,只需要使用哈希函数找到数字在哈希表中的位置即可。

这个算法的时间复杂度是O(1),但是需要额外的空间来存
储哈希表。

4. 递归算法
递归算法是一种将问题分解为更小的子问题的算法。

在查找指定数字时,可以将数字列表分成两个部分,然后递归地在每个部分中查找指定数字。

这个算法的时间复杂度取决于递归的深度和每个递归步骤的复杂度。

总的来说,以上算法都可以用来在给定的n个数中找到指定的数字。

选择哪种算法取决于数字的数量、数据结构的特点以及需要的时间和空间复杂度。

在实际应用中,我们需要根据具体情况选择最合适的算法。

计算机领域常用算法列表

计算机领域常用算法列表在计算机科学领域,算法是解决问题的基础工具。

各种算法的应用领域广泛,包括数据处理、搜索、排序、图形处理、机器学习等。

本文将介绍计算机领域常用的一些算法,以帮助读者了解和熟悉这些算法的基本原理和应用。

一、搜索算法1. 顺序搜索算法顺序搜索算法是最简单的搜索算法之一,其基本思想是按顺序逐个比较目标元素和列表中的元素,直到找到匹配项或搜索完整个列表。

顺序搜索算法适用于未排序的列表。

2. 二分搜索算法二分搜索算法也称为折半搜索算法,适用于已排序的列表。

其基本思想是将列表从中间切分,然后将目标元素与中间元素进行比较,根据比较结果缩小搜索范围,以达到快速搜索的目的。

3. 广度优先搜索算法广度优先搜索算法是一种图遍历算法,用于搜索图或树的结构。

它从起始节点开始,按照广度优先的方式依次访问与当前节点相邻的节点,直到找到目标节点或访问完整个图。

二、排序算法1. 冒泡排序算法冒泡排序算法是一种简单且常用的排序算法。

它通过不断比较相邻的元素并交换位置,将最大或最小的元素逐步“冒泡”到正确的位置,直到整个列表有序。

2. 快速排序算法快速排序算法是一种高效的排序算法。

它通过选择一个基准元素,将列表划分为两个子列表,其中一个子列表的元素都小于基准元素,另一个子列表的元素都大于基准元素。

然后对子列表递归地应用快速排序算法,最终得到有序列表。

3. 归并排序算法归并排序算法是一种稳定的排序算法。

它将列表划分为多个子列表,然后逐个合并子列表,直到得到完全排序的列表。

归并排序算法的核心思想是分治法,将大问题拆分为小问题并解决。

三、图算法1. 最短路径算法最短路径算法用于求解两个节点之间的最短路径。

著名的最短路径算法有迪杰斯特拉算法和弗洛伊德算法。

迪杰斯特拉算法适用于单源最短路径问题,而弗洛伊德算法适用于所有节点对之间的最短路径问题。

2. 最小生成树算法最小生成树算法用于求解连通图的最小生成树。

其中,普里姆算法和克鲁斯卡尔算法是两种常用的最小生成树算法。

计算机领域常用算法列表

计算机领域常用算法列表计算机科学领域是一个不断进步、不断开拓新领域的学科,其中算法是计算机科学中最基本、最核心的学科之一,而在算法学科中,常用算法有很多种,如排序算法、搜索算法、图论算法、数值计算算法等。

在本文中,我们将根据算法的性质和使用范围,介绍一些计算机领域中常用的算法,并说明它们的应用场景和实现原理。

一、排序算法排序算法是计算机科学中非常基本的算法之一。

排序算法可以将待排序的元素按照一定的顺序排列。

目前,常见的排序算法有冒泡排序、选择排序、插入排序、快速排序、堆排序、归并排序等。

它们各自有不同的优点和缺点,应根据实际情况灵活选择。

1. 冒泡排序冒泡排序是一种简单的排序算法,它的基本思想是通过重复遍历要排序的元素,比较相邻元素的大小,如果前面的元素比后面的大,就交换它们的位置。

2. 选择排序选择排序是一种简单的排序算法,它的基本思想是选择最小的元素,并将其放到未排序的开头。

然后从未排序的元素中再选择最小的元素,并将其放到已排序的末尾。

重复此过程,直到所有的元素都被排序。

3. 插入排序插入排序是一种简单的排序算法,它的基本思想是将一个元素插入到已排序序列中的合适位置,从而使序列保持有序。

4. 快速排序快速排序是一种高效的排序算法,它的基本思想是通过一趟排序将待排序的元素分割成独立的两部分,其中一部分元素的值都比另一部分元素的值小,然后将划分出来的两个较小子序列分别递归地进行排序,重复此过程直到整个序列有序。

5. 堆排序堆排序是一种高效的排序算法,它的基本思想是构造大根堆或小根堆,并将待排序的元素依次插入堆中,然后依次取出堆顶元素,保证每次取出的都是当前堆中最大或最小元素,依次放到有序序列的末尾,重复此过程,直到所有元素都被排序。

6. 归并排序归并排序是一种分治算法,它的基本思想是将待排序的序列分成若干个子序列,分别进行递归排序,然后将排好序的子序列合并成一个有序序列。

归并排序也是一种稳定的排序算法。

常用查找算法及其实践应用

常用查找算法及其实践应用查找是计算机科学中常见的操作之一,它的目标是在给定的数据集中寻找特定值或满足特定条件的数据。

常用的查找算法包括线性查找、二分查找、哈希查找和树结构查找等。

本文将对这些算法进行介绍,并探讨它们在实践中的应用。

一、线性查找算法线性查找算法,也称作顺序查找算法,是最简单的查找算法之一。

它的基本思想是逐个遍历数据集中的元素,直到找到目标元素或遍历完整个数据集。

线性查找的时间复杂度为O(n),其中n表示数据集中元素的个数。

线性查找算法的实践应用较为广泛,例如在一个无序数组中查找目标元素、在一个文本文档中搜索关键词等。

由于线性查找算法简单直观,因此在数据量较小或者数据无序的情况下,它是一种有效的查找方法。

二、二分查找算法二分查找算法是一种高效的有序数据查找算法,它的基本思想是通过将数据集划分为两个部分,确定目标元素在哪一部分中,从而快速缩小查找范围。

二分查找的时间复杂度为O(log n),其中n表示有序数据集中元素的个数。

二分查找算法在实践中广泛应用于有序数组或列表的查找操作。

例如,在电话号码簿、字典等有序数据集中查找目标记录,都可以使用二分查找来提高查找的效率。

三、哈希查找算法哈希查找算法是一种基于哈希表的查找方法,它通过将数据元素的关键字进行哈希运算,将其转化为对应的哈希地址,然后在哈希表中查找目标元素。

哈希查找的时间复杂度为O(1)或O(n),其中n表示哈希表中元素的个数。

哈希查找算法在实践中被广泛应用于大型数据库、搜索引擎等需要高效查找的场景。

它通过哈希函数将关键字映射到哈希表中,从而实现快速查找目标元素的目的。

四、树结构查找算法树结构查找算法基于树这种数据结构,它通过将数据集组织成树形结构,然后利用树的特性进行查找操作。

常见的树结构查找算法包括二叉搜索树、平衡二叉树、B树和红黑树等。

树结构查找算法在实践中被广泛应用于文件系统、数据库索引等领域。

例如,在文件系统中根据文件名查找文件、在数据库中根据索引字段查找记录都离不开树结构查找算法的支持。

常用查找算法及其实践应用

常用查找算法及其实践应用查找算法是计算机科学中一种重要的算法,用于在一组数据中查找指定的元素。

常用的查找算法包括顺序查找、二分查找、哈希查找等。

本文将介绍这些常用的查找算法,并探讨它们在实践中的应用。

一、顺序查找顺序查找是最简单的一种查找算法,其基本思想是逐个地比较数组中的元素,直到找到目标元素或者遍历完所有元素。

它适用于无序数组、链表等数据结构。

在实践应用中,顺序查找可以用于查找手机号码通讯录中某个人的联系方式、寻找某本书的索引号等。

虽然顺序查找的时间复杂度较高,但是对于小规模的数据集,其效率仍然可以接受。

二、二分查找二分查找是一种高效的查找算法,前提是数据必须有序。

它的基本思想是将待查找的数据与数组的中间元素进行比较,根据结果缩小查找范围,直到找到目标元素或者范围为空。

在实践应用中,二分查找可以用于在有序数组中查找特定元素,例如在一个升序排列的学生成绩列表中查找某个学生的成绩。

二分查找的时间复杂度为O(logn),相比于顺序查找,它的效率要高很多。

三、哈希查找哈希查找是利用哈希表进行查找的一种算法。

它通过将数据映射到哈希表中的某个位置来进行查找。

当发生哈希冲突时,可以通过链表或者其他方法解决。

在实践应用中,哈希查找广泛用于各种数据库、搜索引擎等系统中,可以快速定位到数据所在的位置,提高查找的效率。

但是它也有一些缺点,比如哈希函数的设计、哈希冲突的处理等问题需要关注。

四、实践应用举例1. 在图书馆管理系统中,通过书名或者作者名进行查找图书的功能,可以使用二分查找算法来实现。

首先将书籍按照书名或者作者名进行排序,然后利用二分查找快速定位到目标书籍的位置。

2. 在电商平台的商品搜索功能中,用户可以通过商品名称进行查找。

为了提高搜索的效率,可以使用哈希查找算法来构建商品名称到商品ID的映射关系,用户输入商品名称时,直接在哈希表中查找对应的商品ID,然后定位到商品详情页。

3. 在各类游戏中,查找某个玩家角色的信息是常见的操作。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

小结
我们通过以上的例子给大家讲解了基本的BFS 搜索,它的重点在于层次上的队列元素的出 队和入队。再者就是判重,防止状态空间树 无穷大而导致RE或者TLE。 注意理解DFS中堆栈和BFS中队列的应用,这 点很重要。 BFS中优先队列的使用,当题目要求在队中找 到最值时,我们应当使用。
例3:Lake Counting(POJ2386) : ( )
题目描述:给定一个矩阵,求它的连通块个 数 样例数据:
样例分析
题目中要求的数据范围长宽不超过100 大家可以看到,题目中说的是八个方向只要 有任意一个方向有块,则它联通。 样例中给的数据显然只有3个块 分析完样例,大家思考一下该怎么做?
算法引入
如果有一滴墨水滴入水中会出现什么现象? 扩散现象! 如果我们利用这种思路能否想出本题的算法呢?
样例分析
题目要求用3中操作对其进行处理。下面我们 来看一下状态树的生成。 5 BFS vs DFS 4 3 2 15 16 17 8 14 7 6 12 13 18 10 9 11 22 20 19 部分状态空间树
算法描述
BFS算法
找到当前节点扩展出来的子节点
BFS+剪枝
当前状态已经不能满足解的条件则剪枝
例4:滑雪(POJ1088) :滑雪( )
Description Michael喜欢滑雪百这并不奇怪, 因为滑雪的确很刺激。可 是为了获得速度,滑的区域必须向下倾斜,而且当你滑到坡 底,你不得不再次走上坡或者等待升降机来载你。Michael想 知道载一个区域中最长底滑坡。区域由一个二维数组给出。 数组的每个数字代表点的高度。下面是一个例子 12345 16 17 18 19 6 15 24 25 20 7 14 23 22 21 8 13 12 11 10 9 一个人可以从某个点滑向上下左右相邻四个点之一,当且仅 当高度减小。在上面的例子中,一条可滑行的滑坡为24-1716-1。当然25-24-23-...-3-2-1更长。事实上,这是最长的一 条。
双向BFS算法 算法 双向
双向BFS算法是将起始状态和目标状态共同进 行BFS搜索,直到他们两个的状态(中间状态 )相同时停止。 这样做的好处是可以减少状态空间的容量。 也可以减少时间的开销,可以时程序达到一 个较优的状态。
DFS与BFS状态操作分析 与 状态操作分析
栈首和栈尾之间的元素为DFS扩展的状态 扩展的状态 栈首和栈尾之间的元素为
算法描述
初始化
本题初始化很简单,我们只需要将存放结果的 变量设为0,并且把矩阵中其中一个点加入BFS 队列之中 r=1; //设置队尾 f=0; //设置队首 res=res+1; //结果加1 d[r][1]=x; //其中一个w点加入队列 d[r][2]=y;
1. 2. 3. 4. 5.
算法描述二
回到例2题目中,我们通过分析,显然用BFS 比较容易实现,而且很直观。下面我们来针 对题目进行分析。 因为有三种操作,我们可以像刚刚所看到的 状态空间树一样去扩展。 直到扩展到目标节点为止。
算法分析
初始化
我们将n加入队列中作为第一个元素q[1]=n,让 队首f=0,队尾r=1;再设一变量t记录拓展的层次
种子填充法!
种子填充法
种子填充算法又称为边界填充算法。其基本 思想是:从多边形区域的一个内点开始,由 内向外用给定的颜色画点直到边界为止。如 果边界是以一种颜色指定的,则种子填充算 法可逐个像素地处理直到遇到边界颜色为止
题目分析
回到题目,由题目我给大家讲解一下种子填 充算法。 首先题目中给定的矩阵很简单,只有两种元 素,一种是”w”表示连通块,一种是”.”表 示分隔个连通块 题目中说到时八个方向任意一个方向有w均可 连通,所以说这个是要区分四向连通的
算法分析二
临界条件的设置:
搜索不是无穷的搜索下去,它必须有个条件来约 束它,这个题目中,当m个盘子都放满苹果时我 们结束搜索。
初始赋值与递归运算:
当程序开始时,我们已经将0个苹果放置到1号盘 子,递归运算的时候,我们将循环值从0到n,这 样子就可以让每个盘子都能放置0到n个苹果,即 便它不符合要求。
代码分析
void dfs(long k, long w) //初始k=1,w=0; k表示现在已用几个盘子,w表示已经放了几个苹果 { long i,u; if (k==m) //当最后一个盘子被放置苹果的时候我们进行判断 { if (n-w>=s[k-1]) { s[k]=n-w; z=z+1; } return; } for (i=0;i<=n;i++) if (i>=s[k-1]) //如果当前放置的苹果个数大于前一个盘子继续放置 { w=w+i; s[k]=i; k=k+1; dfs(k,w); w=w-i; k=k-1; } }
栈顶
队首
队尾
栈底
队首和队尾之间的元素为BFS扩展的状态 扩展的状态 队首和队尾之间的元素为
普通队列与优先队列
有些题目中,我们需要在整个状态空间中找 到一个最值怎么办? 普通队列?
显然达不到要求,因为它的插入是无序的
二叉堆!
二叉堆支持在O(logn)下对堆进行维护并且在O(1) 下找出最值。
题目分析
代码分析二
1. 2. 3. 4. 5. 6. 7.
if (s[a][b+1]=='W') { s[a][b+1]='.'; r=r+1; d[r][1]=a; d[r][2]=b+1; }
小结
这里所讲到的种子填充法,我们既可以用BFS 实现,也可以用DFS实现,这个根据各自的喜 好决定。 种子填充法一般分为4向和8向,实际上也就 是它的扩展规则不同,方法都一样。 种子填充时应当注意处理被填充过的节点, 否则会出现状态无限增大的情况。
//优化剪枝部分
优化前后的对比
搜索题目小结
暴力搜索只能在很小的数据范围内使用,一 般情况下,所谓的暴力也就是枚举了所有的 状态,在这些状态中找到最终的解。在很多 情况下,搜索题目有以下几类:1.求所有状 态的个数,例如放苹果。2.找出所有解的状 态,例如把放苹果的每种方式求出来。3.求 其中一个可行解。4.求出所有可行解的最优 解。
搜索算法例题讲解
史宁 西安电子科技大学ACM基地
例1:放苹果(POJ1664) :放苹果( )
Description 把M个同样的苹果放在N个同样的盘子里,允许有的盘子空着不 放,问共有多少种不同的分法?(5,1,1和1,1,5是同一种 方法) Input 以下每行均包含二个整数M和N,以空格分开。1<=M,N<=10 Output 对输入的每组数据M和N,用一行输出相应的K。 Sample Input 73 Sample Output 8
搜索小结二
搜索题目无外乎上面所说的几类,接下来我们来一一分析下 它们的特点。 求最终状态的个数
这个问题我们有时可以转化为一个组合问题
求出所有最终状态
这个问题是最麻烦,必须对状态空间进行全遍历
求出一种可行状态
这个相对简单,有时候可以用随机化或者当搜索到其中一个解的时候 停止搜索
求出最优可行状态
这个问题可以在问题2的基础上再对状态空间解进行一次扫描。也可Hale Waihona Puke 以转化成动态规划问题数据分析
当n=7,m=3时,有以下几类分法: 007 016 025 034 115 124 133 223
题目分析
这里需要注意两个同样,盘子是相同的,而 且苹果也相同。所以说随意调换盘子和苹果 的位置是可以的。 题目抽象出的数学模型就是把一个数n拆成m 份,使得a1+a2……am=n,0<=ai<=n 接下来我们看下数据规模, 1<=m,n<=10,
main() { int i,u; res=0; intputdata(); //数据输入 for (i=1;i<=n;i++) for (u=1;u<=m;u++) if (s[i][u]==‘W’) //当点为w进行种子填充 bfs(i,u); cout<<res<<endl; //输出结果 }
初始化代码分析
1. 2. 3. 4. 5. 6. 7.
if (k<=n) { printf("%d\n",n-k); return 0; } f=0; r=1; q[1]=n; r1=1; t=0; memset(p,0,sizeof(p)); 注意第7行代码,它的作用是判重 1-5行是一个特殊处理,他的作用是当k<=n时, 只能通过n=n-1的操作来达到最优解,所以说我们 直接输出n-k
枚举矩阵中的每一个元素,当元素为w时对 它进行种子填充(BFS) 种子填充
1. 2.
3.
对八个方向分别扩展加入队列 再对w进行修改,把原有的“w”改为“.”,这样 我们就可以不必再考虑这个点了 用BFS搜索的办法把相邻的点均加入队列,直到 无节点可以扩展
代码分析
1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11.
算法的部分优化
void dfs(long k, long w) { long i,u; if (k==m) { if (n-w>=s[k-1]) { s[k]=n-w; z=z+1; } return; } for (i=0;i<=n;i++) if ((i>=s[k-1])&&((n-w)/(m-k)>=s[k-1])) { w=w+i; s[k]=i; k=k+1; dfs(k,w); w=w-i; k=k-1; } }
很小,暴力搜索可行!
算法分析
相关文档
最新文档