所以我需要从头开始移动第n个元素并将其移到前面(并向右移动0,..,n-1个项目)。什么是最好的数据结构,我应该怎么做呢?
我已经在考虑跳过列表,但不知道如何通过索引获取O(log n)以进行访问。我应该使用更好的东西(树木或其他东西)吗?
提前致谢..
语言:C ++
免责声明:是的,这是作业。
答案 0 :(得分:6)
您可以使用任何平衡二叉树(例如红黑树),在每个节点中缓存存储在该子树中的项目数。物品本身可以存储在树叶中。对于索引查找,可以将索引与左子树的大小进行比较。如果它更小,它就在那里。否则它在右侧,因此从索引中减去左子树的大小以获得相对于右子树的索引。然后递归。由于树是平衡的,因此可以得到O(log n)。
对于其他操作,您可以将现有算法用于红黑树。您只需要进行一些小修改即可跟踪大小。例如,要将项目移到前面,首先使用上述算法找到它,然后将其删除并重新插入前面。这些步骤中的每一步都是O(log n),因此总运行时间也是O(log n)。
答案 1 :(得分:2)
这些问题总是以一个基本原则为中心,您可以将其视为计算机科学的“无免费午餐”:时间和空间之间的权衡。
如果你想快速做某事,你需要消耗更多空间,反之亦然。
例如,数组是小空间的最佳情况,但是当你需要移动某些东西时,它是可怕的。 Hashtable是快速访问的最佳案例,但会消耗过多的浪费空间。
所以你必须决定什么是更重要的,空间经济或时间经济。
在这种情况下,如果要查找索引lokup的O(log n),可以使用跳过列表或索引跳过列表。这些数据结构提供链表的好处(易于将第n个元素移动到前面,只需更改两个指针),具有数组的好处(索引查找),代价是空间(更多指针存储到“跳过”列表。)
答案 2 :(得分:0)
我猜你可以使用LinkedHashMap类DS。在java中有一个内置的LinkedHashMap实现。因此,在第一个位置移动最后一个对象包括删除最后一个对象,然后将其添加到相同的DS。搜索可以在O(1)时间内完成。在其他语言中,使用LinkedList作为主DS实现并不是一件很难的事情,而HashMap DS会随之增强它。
答案 3 :(得分:0)
我不知道空间复杂性,但你可以使用指针和链表的数组在O(1)时间内做同样的事情(你希望数据在数组的情况下如前所述)。制作数字的链接列表和相同大小的数组,以相同的顺序存储linklist节点的地址。对于任何第n个值,从数组中选择第n个节点和第1个节点的地址,并替换这些节点的数量................
答案 4 :(得分:0)
当你使用双向链表时,可能会有双重链表:
索引采用O(n),因为我们需要遍历从开头到所需索引的所有元素。
删除操作很简单,只需要O(1)。
在前面移动所需元素的操作也需要O(1)。
总的来说,你得到~O(n)操作......