数据结构的选择与算法效率
- 格式:doc
- 大小:64.00 KB
- 文档页数:12
选择合适数据结构和算法选择合适的数据结构和算法是优化软件性能的重要步骤,以下是一些建议:1.明确需求:首先,需要明确你的软件需求,包括数据处理速度、存储空间、可扩展性、稳定性等方面的要求。
2.了解数据特点:根据数据的性质和特点选择合适的数据结构。
例如,对于大量数值型数据,可以使用数组或列表;对于有序数据,可以使用二叉搜索树或平衡二叉树等。
3.了解算法特点:同样,需要了解各种算法的特点和适用场景。
例如,对于排序问题,快速排序、归并排序和冒泡排序等算法各有优缺点,需要根据实际情况选择。
4.考虑时间复杂度与空间复杂度:在选择算法时,需要考虑其时间复杂度和空间复杂度。
对于大规模数据或实时性要求较高的场景,需要选择时间复杂度较低的算法。
同时,也需要考虑算法所需的额外空间开销。
5.实际测试:在选择数据结构和算法时,需要进行实际测试和比较。
通过实验,可以了解不同数据结构和算法在实际场景中的表现,从而作出更合理的选择。
6.了解现有工具和库:现代编程语言和开发框架通常提供了许多现成的工具和库,如数据库、缓存系统、搜索算法等。
了解并合理利用这些工具和库,可以更快地实现功能并提高性能。
7.团队技能与经验:还需要考虑团队成员的技能和经验。
如果团队对某种数据结构和算法有丰富的实践经验,那么选择该方案可以降低开发难度和提高开发效率。
8.持续优化:软件需求和技术环境不断变化,因此需要持续关注性能表现并进行优化。
通过监控和分析工具,可以及时发现性能瓶颈并进行针对性的改进。
总之,选择合适的数据结构和算法需要考虑多个方面,包括需求、数据特点、算法特点、时间复杂度、空间复杂度、工具和库、团队技能以及持续优化等。
在实际开发中,可能需要根据实际情况进行综合评估和权衡,以作出最合理的选择。
LabVIEW编程中的数据结构与算法优化技巧在LabVIEW编程中,数据结构和算法的选择与优化对于程序的性能和可维护性至关重要。
本文将介绍在LabVIEW编程中常用的数据结构和算法优化技巧,帮助开发人员提高程序的效率和可靠性。
一、数据结构的选择在LabVIEW编程中,选择合适的数据结构是实现功能的关键。
以下是几种常见的数据结构及其适用场景:1. 数组(Array):用于存储同类型的数据,并且数据的大小是固定的。
数组适用于需要按顺序访问和操作数据的场景,例如存储一组测量数据或图像像素。
2. 队列(Queue):用于实现先进先出(FIFO)的数据存储和访问方式。
队列适用于需要按顺序处理数据的场景,例如数据采集和处理时的数据缓存。
3. 栈(Stack):用于实现后进先出(LIFO)的数据存储和访问方式。
栈适用于需要按相反顺序处理数据的场景,例如函数调用的递归操作。
4. 链表(Linked List):用于存储具有动态长度的数据。
链表适用于频繁插入和删除数据的场景,例如数据缓存和排序等算法。
5. 图(Graph):用于表示多个实体之间的关系,并且这些关系保存在边中。
图适用于复杂网络分析和路径搜索等算法。
在选择数据结构时,需要考虑数据的特性、访问方式和操作需求,以及程序的性能要求等因素,综合评估后选择最合适的数据结构。
二、算法的优化除了选择合适的数据结构之外,优化算法也是提高LabVIEW程序性能的重要手段。
下面是几个常见的算法优化技巧:1. 减少循环次数:循环是LabVIEW程序中常用的操作,但过多的循环会增加程序的执行时间。
在编写程序时,应尽量减少循环次数,例如通过向量化操作或者使用矩阵运算来代替循环运算。
2. 缓存数据:对于需要频繁访问的数据,可以将其存储在缓存中,以减少对内存的访问次数。
例如使用Shift Register或者Local Variable来保存中间计算结果,避免重复计算。
3. 并行计算:LabVIEW支持并行计算,在多核处理器上可以充分利用硬件资源,提高程序的执行效率。
性能优化:如何提升程序的执行效率性能优化是指通过优化程序的设计和实现,提升程序的执行效率,使程序能够更快地完成所需的任务。
以下是一些提升程序执行效率的常见方法。
1.算法优化:选择合适的算法可以大大提升程序的执行效率。
比如,在排序算法中,快速排序的效率远远高于冒泡排序。
对于特定的问题,可以使用专门设计的高效算法,如动态规划或贪心算法。
2.数据结构优化:合理选择和使用数据结构可以提升程序的执行效率。
更高效的数据结构通常具有更快的查找和插入速度。
比如,使用哈希表而不是数组来存储和查找数据。
3.缓存优化:利用缓存可以减少对主存的访问次数,从而提升程序的性能。
合理安排数据和计算的顺序,以利用缓存的局部性原理。
比如,对于多重循环,可以优化循环的顺序,使得每次访问的数据都在缓存中。
4.并行和并发优化:将程序分解为可以并行执行的模块,可以提高程序的执行效率。
比如,使用多线程或多进程并行执行任务,提高程序的利用率。
但需要注意线程同步和资源竞争问题。
5. I/O优化:合理利用缓冲区和操作系统的I/O机制,可以提升程序执行效率。
比如,使用缓冲读写文件,减少对磁盘的访问次数。
可以使用异步I/O来减少I/O等待时间。
6.内存管理优化:减少内存的分配和释放次数,可以提升程序的执行效率。
比如,可以使用对象池来重用对象,避免频繁的内存分配和释放。
7.代码优化:通过改进代码的写法,可以提升程序的执行效率。
比如,避免不必要的循环和条件判断,尽量减少函数调用的次数,减少不必要的内存拷贝等。
8.代码编译优化:选择合适的编译器和编译选项,可以提升程序的执行效率。
比如,使用优化级别较高的编译选项,开启内联函数优化等。
9.数据预处理优化:在程序运行之前,对数据进行预处理,可以减少程序的执行时间。
比如,将静态数据计算和存储在程序中,避免程序运行时的计算。
10.性能测试与优化:通过对程序进行性能测试,找出瓶颈和可优化的地方,并采取相应的优化措施。
优化算法效率的16个技巧优化算法的效率是计算机科学中的重要课题之一。
算法的效率直接影响着程序执行的速度和计算资源的消耗,因此,在编写算法时需要考虑如何优化它们的效率。
下面是不少于1500字的关于优化算法效率的16个技巧。
1.算法分析和设计:在优化算法的效率之前,首先需要分析和设计算法。
通过仔细地考虑问题的特点和算法的需求,可以设计出更加高效的算法。
选择合适的数据结构和算法策略可以大大提高算法的执行效率。
2.时间复杂度分析:时间复杂度是衡量算法执行时间消耗的指标。
通过分析算法的时间复杂度,可以估计算法的执行效率。
选择时间复杂度较低的算法可以提高算法效率。
3.空间复杂度分析:空间复杂度是衡量算法所需存储空间的指标。
通过分析算法的空间复杂度,可以估计算法的内存占用情况。
选择空间复杂度较低的算法可以降低内存消耗。
4.编程语言选择:不同的编程语言有不同的执行性能。
选择性能较好的编程语言可以提高算法的执行效率。
例如,C/C++语言通常比Python语言执行速度更快。
5.数学优化:对于一些数学问题,可以通过数学上的优化方法来提高算法的效率。
例如,利用数学公式的特性,可以简化计算过程,减少重复计算等。
6.数据压缩和编码:对于一些大规模的数据集合,可以采用数据压缩和编码算法来减小数据的存储空间,从而提高算法执行效率。
例如,使用哈夫曼树算法对文本进行压缩。
7.并行计算:对于一些计算密集型的算法,可以利用并行计算的方式来提高算法的执行效率。
通过将任务分解成多个子任务,并行执行,可以加快算法的处理速度。
例如,使用多线程或多进程的方式进行并行计算。
8.空间换时间:在一些情况下,可以通过牺牲存储空间来提高算法的执行效率。
例如,使用缓存来存储计算结果,避免重复计算,从而加快算法的执行速度。
9.数据预处理:对于一些算法,在执行之前,可以对数据进行一些预处理,从而减少算法的运行时间。
例如,对数据进行排序,可以提高搜索算法的效率。
理解数据结构和算法的六个关键点数据结构和算法是计算机科学中非常重要的概念,对于计算机程序的设计和效率至关重要。
在学习和应用数据结构和算法时,有六个关键点需要理解和掌握。
一、选择合适的数据结构数据结构是组织和存储数据的方式,不同的数据结构适用于不同的问题和操作。
在解决问题之前,我们需要仔细考虑问题的特点以及对数据的访问和处理方式,选择最合适的数据结构。
比如,对于需要频繁插入和删除元素的问题,链表可能是更好的选择;而对于需要快速查找和排序的问题,数组或者树结构可能更合适。
二、理解数据结构的基本操作每种数据结构都有自己的基本操作,比如插入、删除和查找等。
熟悉并理解这些基本操作对于充分利用数据结构的优点和解决问题至关重要。
例如,对于链表,我们需要了解如何在指定位置插入或删除节点,以及如何遍历链表并查找特定的元素。
三、掌握常用的算法技巧算法是解决问题的步骤和方法。
有许多常用的算法技巧,比如递归、分治、贪心和动态规划等。
每种算法技巧都有自己的适用场景和解决问题的特点,掌握这些技巧并能够灵活应用是提高算法效率的关键。
四、分析算法的时间复杂度和空间复杂度分析算法的时间复杂度和空间复杂度可以帮助我们评估算法的效率,并进行算法选择和优化。
时间复杂度是算法执行所需的时间随输入规模增长的趋势,空间复杂度是算法执行所需的存储空间随输入规模增长的趋势。
理解这些概念并能够分析算法的复杂度是设计高效算法的关键。
五、解决实际问题时的抽象能力数据结构和算法的学习不仅仅局限于理论,更重要的是能够将其应用于实际问题的解决。
具备良好的抽象能力可以将实际问题抽象为适合运用特定数据结构和算法的模型,从而更好地解决问题。
通过实践和经验的积累,我们能够更好地运用数据结构和算法解决实际问题。
六、不断学习和实践数据结构和算法是一个广阔的领域,没有捷径可走。
持续学习和实践是提高理解和应用数据结构和算法的最佳途径。
通过参与实际项目、解决实际问题和和其他开发者的交流等方式,我们可以不断提高自己的能力和经验。
算法和数据结构的4种关系一、算法与数据结构的关系算法和数据结构是计算机科学中两个密切相关的概念。
算法是解决问题的一系列步骤或指令,而数据结构是组织和存储数据的方式。
算法和数据结构之间存在着紧密的联系和相互依赖关系。
算法的设计和效率与所使用的数据结构密切相关。
不同的数据结构适用于不同类型的问题,选择合适的数据结构可以提高算法的效率。
例如,对于需要频繁插入和删除操作的问题,链表数据结构比数组更加高效。
算法的实现通常需要使用数据结构来存储和操作数据。
例如,排序算法通常需要使用数组或链表来存储待排序的数据。
数据结构的选择和实现方式会直接影响算法的正确性和效率。
算法和数据结构的研究相互促进。
算法的设计和分析需要考虑到所使用的数据结构,而对数据结构的研究也需要考虑到算法的需求。
算法和数据结构的研究成果相互借鉴,推动了计算机科学的发展。
二、算法与数据结构的分类关系算法和数据结构可以按照不同的分类方式进行划分。
下面介绍四种常见的分类关系。
1. 线性结构与非线性结构线性结构是指数据元素之间存在一对一的关系,例如数组和链表。
非线性结构是指数据元素之间存在一对多或多对多的关系,例如树和图。
算法和数据结构的设计和分析需要考虑到数据元素之间的关系,因此线性结构和非线性结构是算法和数据结构分类的重要依据。
2. 静态结构与动态结构静态结构是指数据结构的大小和形式在创建后不可改变,例如数组。
动态结构是指数据结构的大小和形式可以根据需要进行动态调整,例如链表。
算法和数据结构的设计和实现需要考虑到数据结构的静态性或动态性,以及相应的操作和调整方式。
3. 存储结构与逻辑结构存储结构是指数据结构在计算机内存中的表示方式,例如数组和链表。
逻辑结构是指数据元素之间的逻辑关系,例如线性结构和非线性结构。
算法和数据结构的设计和实现需要考虑到存储结构和逻辑结构之间的映射关系,以及相应的操作和访问方式。
4. 基本结构与扩展结构基本结构是指常见的数据结构,例如数组、链表、栈和队列。
数据结构的设计原则与方法数据结构是计算机科学中的重要概念,它指的是组织和存储数据的方式。
良好的数据结构设计可以提高程序的效率和性能,并且对于解决实际问题非常重要。
在本文中,我们将探讨数据结构的设计原则和方法。
一、数据结构的设计原则1. 高效性原则:好的数据结构应该可以在最优时间内完成各种操作,如插入、删除、查找等。
因此,在设计数据结构时,我们应该考虑选择适合特定问题的数据结构,并确保其操作的时间复杂度尽可能低。
2. 空间利用原则:数据结构的设计应该尽量节约内存空间。
对于大规模数据处理和存储需求较高的应用程序,合理利用内存是非常重要的。
我们可以通过使用压缩算法、减少冗余数据等方式来最大限度地节约空间。
3. 易用性原则:数据结构应该易于使用和操作。
一个好的数据结构应该具备清晰的接口和简单的操作方法,使得开发人员能够方便地使用它进行编程。
4. 扩展性原则:数据结构应该具有良好的扩展性,能够适应未来需求的变化。
我们应该预留足够的空间和接口,以便在需要时能够方便地进行扩展。
二、数据结构的设计方法1. 抽象数据类型(ADT):ADT是指对数据的一种抽象描述,它定义了数据的逻辑结构和操作,而不关心具体实现细节。
通过使用ADT,我们可以将数据结构和操作进行解耦,从而提高代码的可维护性和可重用性。
2. 选择合适的数据结构:不同的问题适合使用不同的数据结构来解决。
例如,对于需要频繁插入和删除操作的问题,链表可能是一个更好的选择;而对于需要高效查找的问题,树和哈希表可能更合适。
因此,在设计数据结构时,我们应该根据问题的特点选择合适的数据结构。
3. 分治法:分治法是一种将问题分解为多个子问题,并解决这些子问题的方法。
在数据结构的设计中,我们可以将大型数据结构拆分成多个小型数据结构,然后分别处理。
通过这种方式,我们可以简化问题的复杂度,提高程序的效率。
4. 动态规划:动态规划是一种将问题划分为多个子问题,并使用表格或数组记录每个子问题的最优解的方法。
算法的基本要素算法是计算机科学的核心,它是解决问题的有效方法和步骤。
算法的设计需要遵循一定的规则和原则,其中最基本的要素包括:输入、输出、数据结构、控制结构、正确性和效率。
一、输入和输出输入和输出是算法的基本要素之一。
输入是指将问题中的数据输入到计算机中,输出是指计算机输出问题的答案。
在算法中,输入和输出的数据类型和格式需要明确规定。
例如,一个求两个数之和的算法,输入需要明确指定两个数的数据类型和格式,输出需要明确指定结果的数据类型和格式。
二、数据结构数据结构是指将数据以特定的方式组织和存储的方法。
在算法中,数据结构的选择对算法的效率有很大的影响。
常见的数据结构包括数组、链表、栈、队列、树等。
选择合适的数据结构可以大大提高算法的效率。
例如,对于查找某个元素的算法,使用数组需要遍历所有元素,时间复杂度为O(n),而使用哈希表可以将查找时间复杂度降低到O(1)。
三、控制结构控制结构是指通过条件判断和循环来控制算法的执行流程。
常见的控制结构包括if语句、for循环、while循环、switch语句等。
在算法中,控制结构的选择可以使算法更加简洁明了,也可以使算法更加高效。
例如,对于一个排序算法,使用冒泡排序的时间复杂度为O(n^2),而使用快速排序的时间复杂度为O(nlogn),可以大大提高算法的效率。
四、正确性算法的正确性是指算法可以正确地解决问题。
在设计算法时,需要考虑各种情况和可能出现的错误。
通过数学证明和测试可以验证算法的正确性。
例如,对于一个排序算法,需要验证是否能够正确地将数组按照要求排序。
五、效率算法的效率是指算法解决问题所需要的时间和空间复杂度。
在设计算法时,需要考虑算法的时间和空间的复杂度。
时间复杂度通常用大O符号表示,表示算法的运行时间与问题规模的增长率。
空间复杂度是指算法所需要的存储空间。
例如,对于一个求斐波那契数列的算法,使用递归算法的时间复杂度为O(2^n),而使用循环算法的时间复杂度为O(n),可以大大提高算法的效率。
算法和数据结构的关系算法和数据结构是计算机科学中最基本的两个概念,它们的关系密不可分。
算法是解决问题的方法,数据结构是数据的组织形式。
算法和数据结构的设计和选择直接关系到程序的效率和质量。
算法和数据结构的关系算法和数据结构是密切相关的,它们相互依存,彼此支持。
算法是基于数据结构的,数据结构是算法的基础。
算法需要数据结构来存储和处理数据,而数据结构则提供了算法所需要的数据操作接口。
因此,算法和数据结构是相互依存,彼此支持的关系。
在程序设计中,算法的效率和质量直接受到数据结构的影响。
数据结构的选择和设计对算法的效率和质量有着重要的影响。
因此,算法和数据结构的设计和选择是程序设计中最基本的问题之一。
数据结构的种类数据结构是计算机科学中的重要概念,它是指数据元素之间的关系以及数据元素的组织形式。
数据结构分为线性结构和非线性结构两种。
线性结构是指数据元素之间的关系是一对一的关系,其中包括线性表、栈、队列、串等。
线性表是最基本的数据结构,它是一种有序的数据元素集合。
栈是一种特殊的线性表,它只允许在表的一端进行插入和删除操作。
队列也是一种特殊的线性表,它只允许在表的一端进行插入操作,在另一端进行删除操作。
串是由零个或多个字符组成的有限序列,它是一种特殊的线性表。
非线性结构是指数据元素之间的关系不是一对一的关系,其中包括树、图等。
树是一种非线性结构,它由若干个节点组成,节点之间的关系是一对多的关系。
图是一种非线性结构,它由若干个节点和连接这些节点的边组成,节点之间的关系是多对多的关系。
算法的设计与实现算法的设计与实现是程序设计中最基本的问题之一。
算法的设计需要考虑到问题的特点、数据结构的选择和算法的效率等因素。
算法的实现需要考虑到语言的特点、程序的可读性、可维护性和可扩展性等因素。
算法的设计过程包括问题分析、算法设计、算法评估和算法改进等步骤。
问题分析是指对问题进行深入的分析和理解,找出问题的本质和特点。
算法设计是指根据问题的特点和数据结构的选择,设计出符合要求的算法。
编程技巧:优化算法的十大方法在软件开发过程中,编写高效的算法是非常重要的。
优化算法能够提升程序的性能,并节约计算资源。
下面列举了编程中常用的十种优化算法方法。
1. 时间复杂度分析在选择合适的算法之前,首先需要对各个算法的时间复杂度进行分析。
通过衡量一个算法在不同规模下运行所需的时间,可以帮助我们选择更高效的算法。
2. 空间复杂度优化除了考虑到时间复杂度,在编程中也要注意空间复杂度。
尽量减少内存使用和数据结构占用,避免造成资源浪费。
3. 算法设计精简通过合理地设计算法,可以避免额外操作和不必要的计算。
需要思考如何通过简单而有效的方式解决问题,以减小计算量。
4. 数据结构选取根据具体问题选择恰当的数据结构非常重要。
不同数据结构有着不同特点和适用场景,正确选择能够提高程序效率。
5. 迭代和递归比较在编写循环迭代和递归函数时,需要权衡两者的优劣。
在某些情况下,递归可以更好地解决问题。
6. 缓存利用利用缓存机制能够加速程序运行。
考虑到数据访问和缓存命中率,合理使用缓存可以提高程序性能。
7. 并行计算现代 CPU 支持并行计算,通过合理并发设计,可以充分利用多核处理器的优势。
并行计算可以显著加快程序运行速度。
8. 状态压缩技巧对于某些状态空间较大的问题,使用状态压缩方法能够减小内存占用,并提高算法效率。
9. 剪枝和预处理在搜索类问题中,通过剪枝和预处理能够减少搜索空间,从而降低算法复杂度。
10. 算法改进和优化通过不断改进和优化原始的算法实现,比如利用数学定理、近似方法或其他技术手段来提高算法效率。
以上十种优化算法方法只是一部分常见的技巧。
在实际编程过程中,需要根据具体问题选择合适的方法来进行优化。
通过对算法进行细致分析和不断实践与总结,我们可以编写出更高效、更优化的程序。
数据结构的选择与算法效率
——从IOI98试题PICTURE谈起
福建师大附中陈宏
【关键字】
数据结构的选择线性结构树形结构
【摘要】
算法 + 数据结构=程序。
设计算法与选择合适的数据结构是程序设计中相辅相成的两方面,缺一不可。
数据结构的选择一直是程序设计中的重点、难点,正确地应用数据结构,往往能带来意想不到的效果。
反之,如果忽视了数据结构的重要性,对某些问题有时就得不到满意的解答。
通过对IOI98试题Picture的深入讨论,我们可以看到两种不同的数据结构在解题中的应用,以及由此得到的不同的算法效率。
本文以Picture问题为例,探讨数据结构的选择对算法效率的影响。
【正文】
引言
算法通常是决定程序效率的关键,但一切算法最终都要在相应的数据结构上实现,许多算法的精髓就是在于选择了合适的数据结构作为基础。
在程序设计中,不但要注重算法设计,也要正确地选择数据结构,这样往往能够事半功倍。
在算法时间与空间效率的两方面,着重分析时间效率,即算法的时间复杂度,因为我们总是希望程序在较短的时间内给出我们所希望的输出。
如果在空间上过于“吝啬”而使得时间上无法承受,对解题并无益处。
本文对IOI98的试题Picture作一些分析,通过两种不同数据结构的选择,将了解到数据结构对算法本身及算法效率的影响。
Picture问题及算法设计
一、Picture问题
Picture问题是IOI98的一道试题,描述如下:
墙上贴着一些海报、照片等矩形,所有的边都为垂直或水平。
每个矩形可以被其它矩形部分或完全遮盖,所有矩形合并成区域的边界周长称为轮廓周长。
例如图1的三个矩形轮廓周长为30:
图1
要求编写程序计算轮廓周长。
数据量限制:
0≤矩形数目<5000;
坐标数值为整数,范围是[-10000,10000]。
二、算法描述
在算法的大体描述中,将不涉及到具体的数据结构,便于数据结构的进一步选择和比较分析。
(一)、轮廓的定义
在描述算法前,我们先明确一下“轮廓”的定义:
1、轮廓由有限条线段组成,线段是矩形边或者矩形边的一部分。
2、组成矩形边的线段不应被任何矩形遮盖。
图2与图3分别是遮盖的两种情况。
图2 图3 图4
(AB被遮盖)(CD被遮盖)
(二)、元线段
本题的一大特征是分析矩形的边,而边的端点(即矩形的顶点)坐标为整数,且坐标取值范围已经限定在[-10000,10000]之间。
这样,就可以把这个平面理解成为一个网格。
由于给出的坐标是整数,所以矩形边一定在网格线上。
在网格中,对于一条线段我们最关心其绝对坐标。
如图4,我们认为矩形边AB由线
段L
1、L
2
、L
3
组成。
像L
1
、L
2
、L
3
这样连接相邻网格顶点的基本线段,称之为“元
线段”,这样就把矩形边离散化了。
显然,有限的元线段覆盖了所有的网格线,且元线段是组成矩形边乃至组成轮廓的基本单位。
一条元线段要么完全属于轮廓,要么完全不属于轮廓。
这种定义使我们对问题的研究具体到每一条元线段,这样的离散化处理有利于问题的进一步讨论。
(三)、超元线段
元线段的引入,使问题更加具体。
但也应当看到,平面中共有20001*20000*2条元线段,研究的对象过多,而且计算量受到网格大小的影响,如果顶点坐标范围是[-1,000,000,1,000,000],元线段数目将达到8*10^12,这是天文数字。
因此有必要对“元线段”进行优化。
受到元线段的启发,我们定义一种改进后的元线段——“超元线段”,它将由对平面的“切割”得到。
具体做法是,根据每个矩形纵向边的横坐标纵向地对平面进行2*N次切割、根据矩形横向边的纵坐标横向地对矩形进行2*N次切割(N为矩形个数)。
显然,经过切割后的平面被分成了(2*N+1)^2个区域,如图5所示:
图5 图6
其中像横向边AB、纵向边CD这样的线段就是“超元线段”。
超元线段与元线段有着相似的性质,也是组成轮廓的基本单位。
所不同的是,超元线段的数目较少,一般为4*N条左右,且超元线段数目不受网格大小的影响。
基于超元线段的优点,算法最终将研究超元线段。
(一)、离散化及算法框架
算法的研究对象是超元线段,但这并不等于逐一枚举,那样耗时过大,而整体考虑又使得问题无从下手。
有一种考虑方法是折中的,即既不研究每一条超元线段,也不同时研究所有的超元线段,而是再进一步优化问题的离散化,即将超元线段分组研究。
如图6所示,夹在两条纵向分割边的超元线段自然地分为一组,它们的共同点是长度相同,并且端点的横坐标相同。
纵向线段也可以进行类似的离散化。
这样的离散化处理后,使得问题规模降低,以此为基础,算法的框架可以基本确定为:
1、对平面进行分割。
2、累加器ans 0。
3、研究每组超元线段,检测其中属于轮廓的部分的长度,并把这一长度累加入ans。
4、输出ans的值。
以上只是算法的基本框架,还很粗糙,求精部分有赖于数据结构的具体选择。
三、Picture问题的数据结构选择之一:线性结构
(一)、映射结构的建立
算法的基础是问题的离散化,要进行平面“分割”,一般需要记录分割点,通常采用映射来记录分割点。
直观的做法是采用一维数组形式,下标表示分割点的编号,数组元素表示分割点的坐标。
利用下标与数组元素的自然对应,实现映射。
应该说,这样表示是比较自然的,实现也比较方便。
数组的优点主要是存取方便,且可以在O(NlogN)时间内排序。
映射结构定义如下:
Type
Mapped_TYPE = Object
Len : 0..Max; {记下分割点的个数}
Coord : array[1..Max] of integer; {记下分割点坐标}
Procedure Creat; {映射初始化}
Procedure Insert(X : integer); {插入分割坐标X}
Procedure Sort; {对坐标排序}
End
以下是三个过程的描述与解释:
Procedure Mapped_TYPE.Creat
1Len ← 0
{Creat 用于初始化该映射}
Procedure Mapped_TYPE.Insert(X : Integer)
1Len ←Len + 1
2Coord[Len] ←X
{Insert 用于插入一个分割坐标,此时坐标之间是无序的}
Procedure Mapped_TYPE.Sort
略
{Sort 用于将Len个坐标排序。
由于Coord是一维数组,Sort 容易实现,例如快速排序。
设N = Len,Sort 效率可达O(NlogN)。
针对整数,也可以采用筒排序得到更好的效率,但这不是问题的关键部分。
}
Var
X_map, Y_map : Mapped_TYPE {分别记录横纵坐标的映射} 以横坐标为例,在程序处理时,首先执行X_map.Creat初始化映射。
而后通过X_map.Insert将每个矩形纵向边的横坐标作为分割坐标插入X_map.Coord,最后执行X_map.Sort进行排序。
至此,映射建立完毕。
应该说,这一部分完全可以满足算法要求,且执行效率较高。
三个过程中的Creat与Insert耗时均为O(1),Sort耗时为O(NlogN),但它只需执行一次。
(二)、线性结构的建立
映射建立后,相当于完成了对平面的切割。
现在的主要问题是如何描述一组超元线段的状态。
由于最终要计算轮廓周长,我们最关心的是一组超元线段中究竟有多少条属于轮廓。
由分组的方法可知,每组超元线段长度相同。
以下均以横向超元线段为例进行说明。
设:
超元线段组编号1——N*2-1(N是矩形数目)
编号为S的超元线段组中的线段长度为Length(S)
编号为S的超元线段组中属于图形轮廓的超元线段数目为Belong(S)
则:
N
2*
-1。