对于事务队列,是否存在比使用List更合适/更有效的数据结构。我已经尝试过使用队列和堆栈,但两者都没有正确地适应账单。
我在下面详细介绍了我的问题,并举例说明了为什么我暂时最终得到了一个List。任何关于替代数据结构的建议(最好但不限于那些在.Net BCL中实现的建议)都表示赞赏。
维护Insert()
/ Delete()
个操作的事务队列,稍后当用户调用Commit()
方法时将其保留到任意后备存储,或者在调用{{1}时丢弃方法。
必须对受影响对象的内存中状态执行操作,因为后续操作可能依赖于先前操作创建的对象的状态。
我有一个对象Rollback()
,它以空集合开头。用户插入项obj
,然后删除项i
。
然后他们调用i
,给定队列的以下数据结构,在回滚中发生以下情况:
Rollback()
,obj.Delete(i)
- >不正确,因为obj.Insert(i)
在回滚后应保持为空obj
,obj.Insert(i)
- >正确,因为obj.Delete(i)
仍为空obj
,obj.Insert(i)
- >正确,因为obj.Delete(i)
仍为空如果他们拨打obj
,则会发生以下情况:
Commit()
,obj.Insert(i)
- >正确,因为obj.Delete(i)
仍为空obj
,obj.Delete(i)
- >不正确,因为obj.Insert(i)
不为空obj
,obj.Insert(i)
- >正确,因为obj.Delete(i)
仍为空因此,对于此示例,队列适用于obj
但不适用于Commit()
,而堆栈显示反向行为但两者都不正确。只有列表显示正确的行为,但请注意,对于提交,我们以正向方向遍历列表,而对于回滚,我们以反方向遍历列表。
现在考虑再次使用一个对象Rollback()
,这次以包含在其中的单个项目obj
开头。
这次操作的顺序是删除i
,然后插入i
。
如果他们致电i
,则会发生以下情况:
Rollback()
,obj.Insert(i)
- >不正确,因为obj.Delete(i)
最终为空obj
,obj.Delete(i)
- >正确,因为obj.Insert(i)
包含单个项obj
仍然i
,obj.Delete(i)
- >正确,因为obj.Insert(i)
包含单个项obj
仍然如果他们改为呼叫i
,则会发生以下情况:
Commit()
,obj.Delete(i)
- >正确,因为obj.Insert(i)
包含单个项obj
仍然i
,obj.Insert(i)
- >不正确,因为obj.Delete(i)
最终为空obj
,obj.Delete(i)
- >正确,因为obj.Insert(i)
包含单个项obj
仍然与前面的示例一样,在这两种情况下只使用List是正确的,但我们必须根据我们是提交还是回滚来在不同的方向上遍历它。
虽然使用List本身并不低效,但我只是想知道是否有更合适的数据结构更适合我的问题?
答案 0 :(得分:1)
从技术上讲,您可以使用LinkedList<T>
。这就像Queue
+ Stack
:你可以从头部和尾部添加和删除,在两种情况下它都是O(1)(但它通常比List慢,原因是连接到内存局部性并且需要为每次添加元素分配内存)
(请不要杀我,因为我说LinkedList<T>
就像Queue
+ Stack
...我知道差异......我的意思只是它可以是同时用于两种方式)
我要补充一点,如果您认为Rollback
是“例外”(很少见),那么您可以使用Queue
,当您拥有Rollback
时{} 1}}使用LINQ的Reverse
的输出。作为一个“例外”,它可能会更慢(你甚至不需要LINQ ......你可以做Queue
并以相反的顺序遍历数组)