我在 C 中有一个循环的、静态分配的缓冲区,我将其用作深度广度优先搜索的队列。我希望对队列中的前 N 个元素进行排序。只使用常规的 qsort() 会很容易——除了它是一个循环缓冲区,并且前 N 个元素可能会环绕。当然,我可以编写自己的排序实现,它使用模块化算法并且知道如何环绕数组,但我一直认为编写排序函数是一个很好的练习,但最好留给库。
我想到了几种方法:
- 使用单独的线性缓冲区 - 首先从循环缓冲区复制元素,然后应用 qsort,然后将它们复制回来。使用额外的缓冲区意味着额外的 O(N) 空间需求,这让我
- 使用 qsort 对“顶部”和“底部”两半进行排序,然后使用附加缓冲区将它们合并
- 与 2 相同。但在原地进行最终合并(我在原地合并方面没有发现太多,但我看到的实现似乎不值得降低空间复杂度)
另一方面,花一个小时思考如何优雅地避免编写我自己的快速排序,而不是添加那 25 行(左右)行可能也不是最有效率的......
更正:在切换 DFS 和 BFS 时犯了一个愚蠢的错误(我更喜欢编写 DFS,但在这种特殊情况下我必须使用 BFS),抱歉造成混淆。
原问题的进一步描述:
我正在实施广度优先搜索(对于类似于十五个难题的东西,只是更复杂,在每个状态下大约有 O(n^2) 个可能的扩展,而不是 4 个)。“蛮力”算法已经完成,但它是“愚蠢的”——在每一点,它以硬编码的顺序扩展所有有效状态。队列实现为循环缓冲区(无符号队列[MAXLENGTH]),它将整数索引存储到状态表中。除了对索引进行排队和出队的两个简单函数外,它没有封装——它只是一个简单的、静态分配的无符号数组。
现在我想添加一些启发式方法。我想尝试的第一件事是在展开后对展开的子状态进行排序(“以更好的顺序展开它们”)——就像我正在编写一个简单的最佳优先 DFS 一样。为此,我想加入队列(代表最近的扩展状态),并使用某种启发式对它们进行排序。我还可以以不同的顺序扩展状态(因此在这种情况下,如果我打破队列的 FIFO 属性并不重要)。
我的目标不是实现A*或基于深度优先搜索的算法(我无法扩展所有状态,但如果我不这样做,我将开始遇到状态空间中无限循环的问题,所以我必须使用诸如迭代深化之类的东西)。