如何在插入点后不重新索引/移动项目的情况下将数据插入到有序、随机可访问的列表中?

Posted

技术标签:

【中文标题】如何在插入点后不重新索引/移动项目的情况下将数据插入到有序、随机可访问的列表中?【英文标题】:How to insert data to an ordered, random accessible list without re-index/moving items after insertion point? 【发布时间】:2014-11-28 03:20:08 【问题描述】:

我正在开发一个 Qt 自定义小部件,它可以显示给定文件夹中的所有文件。除了速度,一切都很好。

小部件可以按以下顺序显示项目:

    所有文件分为 4 组:图像、音频、视频和其他。 每个组中的所有文件都按扩展名和基名排序。

此外,小部件是随机访问的。用户可以滚动到任何地方以显示相应的项目。用户还可以隐藏或显示任何一组项目。

widget的内部数据结构是:

    上述组的 4 个全局有序双端队列。 遍历线程将新项目插入到 4 个有序的本地双端队列。 (使用二分查找来定位插入点) 如果本地双端队列已满,请将它们转储到全局双端队列。 (使用归并排序)这样可以减少全局双端队列的独占访问频率。

开始时表现不错。但是当数据变大时它变得越来越慢(阈值约为100,000)。在调查了代码后,我发现根本原因是双端队列的重新索引和数据移动。

deque 基本上是一个数组或指针。为了保持索引,它必须在插入后向前移动指针(重新索引)。如果数据量很大,这个动作会花费太多时间,成为性能的瓶颈。

我尝试了 set 和 map。它们都不能很好地替代双端队列或向量。 set 不能通过简单的数字索引访问(它是通过 item 的 hash 来索引的),并且 map 是按索引排序的。

我需要一个满足以下条件的结构:

    提供有序(按项目内容)列表。 可以通过简单的递增数字索引进行访问。 插入速度非常快。

谁能帮帮我?

【问题讨论】:

A skip list 提供 O(log n) 的键插入和查找,但 O(n) 的索引查找。哪个可能足以满足您的需求。但是如果你想要 O(log n) 索引查找,你可以创建一个可索引的跳过列表。所需的修改在链接的文章中。快速搜索“skip list C++”会发现您可以使用的几个实现。 好的,我会尝试跳过列表。谢谢!! 【参考方案1】:

用一棵树怎么样。

其实我觉得QList已经足够好了。

在您的 UI 小部件中,您无需一次设置所有文件小部件,只需设置将显示的那些。就像一个虚拟列表。

试试 Qt 的 Model View,使用一个模型来保存被排序的真实数据,并且只设置需要显示的视图项。

【讨论】:

树确实很容易插入。但是每次插入后都需要重新索引......我试过qt的模型视图。但问题仍然存在。内部数据结构由工作线程不断更新。当文件数量变大时,每次插入都需要很长时间。

以上是关于如何在插入点后不重新索引/移动项目的情况下将数据插入到有序、随机可访问的列表中?的主要内容,如果未能解决你的问题,请参考以下文章

如何在不生成 SettingWithCopyWarning 的情况下将列插入 DataFrame

如何在不重新加载页面的情况下将用户重定向到 redux saga 上的另一个页面

如何在不将数据输入自动编号列的情况下将数据插入 MS Access 表?

如何在不跟踪索引的情况下将元素附加到列表?

Gstreamer:如何在不重新编码的情况下将 rtpvp8depay 导入 webmmux?

如何在不手动滚动的情况下将 HMSegmentedControl 水平滚动到所选索引