关于STL数据结构的建议

时间:2011-07-12 10:16:17

标签: c++ algorithm stl

我正在实现一种显示算法,我们可以根据它们的z顺序拥有多层窗口,即我从最后一个z值开始并合并图像,直到我们将z值设为0的图像为止最佳。 要保持z值,您建议使用哪种数据结构?

例如:如果z顺序是2 3 4 5 1 6 7 8 9 10(应用程序的索引),如果用户点击了应用程序5的窗口,那么我们需要将5移动到前面并且剩余的顺序应该是相同的,即5 2 3 4 1 6 7 8 9 10。

如果我使用矢量,那么每次重新排列元素(或复制值)似乎效率不高。 如果我使用deque,那么push_front有一些明显的优势,但再次将Application从其先前的位置移除是问题所在。 如果我使用list,那么每次我们需要搜索元素并将其删除。 有关哪种数据结构对我的目的最有效的想法?

6 个答案:

答案 0 :(得分:5)

鉴于窗口的数量可能是最小的,我可能会使用(智能)指针向量,并重新排序矢量组件。虽然复杂性高于其他替代方案,但实际性能并不差,因为常量可能会主导复杂性。

答案 1 :(得分:3)

显而易见的答案是使用boost multi-index。但是,这有时会变得棘手。您可以通过两种结构来模拟它:

  • 存储订单和值的列表
  • 将值映射到列表位置的地图

所以,你可以这样:

typedef std::list<int> pos_list_t;
pos_list_t positions;
std::map<int, pos_list_t::iterator> position_map;

然后,每次你必须搜索和改变位置时,你可以做类似的事情(简化,但你明白了):

pos_list_t::iterator pos = position_map[window_number];
// pos takes the list iterator. You can move it to the beginning
positions.erase(pos);
positions.push_front(window_number);
// update the map position
position_map[window_number] = positions.begin(); // iterator of the new position. The beginning.

您还需要一些联合初始化:

positions.push_back(value1);
positions.push_back(value2);
...
for (pos_list_t::iterator it = positions.begin(); it != positions.end(); ++it)
    position_map[*it] = it;

答案 2 :(得分:2)

你实际要做的是:

  1. 在特定位置找到元素
  2. 在开头插入新元素
  3. 删除某个位置的元素
  4. 遍历元素
  5. 因此,如果您使用列表 - 您遇到麻烦1.如果您使用地图。你遇到麻烦4。 我会说对于1,2和4具有常量的向量。并且对于需要从集合中删除的元素使用某种标记。由于你可能不会拥有数百万个窗口,你可以在矢量中执行内务管理非常罕见,例如在10秒内完成一次。

答案 3 :(得分:1)

看起来像一个简单的链表在这里最方便,然后根据它们的z值对它们进行排序。

答案 4 :(得分:1)

您可以使用一个地图,其中键是识别窗口所需的任何内容,值是窗口的位置。我们假设我们使用HWND来识别窗口。

 map<HWND, int> windows

在开始时,您必须初始化地图并为每个窗口设置正确的位置。防爆。 windows [0x0002] = 0; windows [0x0003] = 1; 地图将根据价值进行排序。 当您必须将窗口置于前面时,您只需要使用0顺序窗口切换其位置

int temp_order = windows[bringToFrontWindow]; 
HWND front_window = windows.begin().first; // the fist window of the map has 0 z-order
windows[bringToFrontWindow] = 0;
windows[front_window] = temp_order;

答案 5 :(得分:1)

我在这里只使用std::list,因为1)列表迭代器永远不会失效(除非从列表中删除对象)2)分割是恒定时间(因为我们正在讨论小列表,所以并不重要)。

您可以维护std::list<Window*>,并在std::list<Window*>::iterator类中捆绑Window(假设有一些Window类来管理窗口的资源)