简体   繁体   English

ArrayDeque 操作

[英]ArrayDeque operations

I am having some free time and trying to understand how ArrayDeque works internally.我有一些空闲时间并试图了解 ArrayDeque 的内部工作方式。 I've read a couple of articles and questions/answers here and I think I'm pretty close.我在这里阅读了几篇文章和问题/答案,我认为我已经很接近了。 I used debugging to follow the workflow and there is something that's bothering me.我使用调试来跟踪工作流程,但有些事情困扰着我。 I created an empty deque which resulted in an array with 16 elements which are null. When I used addFirst it added an element on position 16 in the array and addLast added in the beggining on position 0. What am I missing, can you please share some knowledge or point me in the right direction so I can fully understand what is happening behind the curtains.我创建了一个空双端队列,它产生了一个包含 16 个元素的数组,即 null。当我使用addFirst时,它在数组中的 position 16 上添加了一个元素,并在 position 0 的开头添加了addLast 。我缺少什么,你能分享一下吗一些知识或为我指明正确的方向,以便我可以完全了解幕后发生的事情。 Thanks in advance!提前致谢!

An array-based deque is typically implemented using a data structure called a circular buffer .基于数组的双端队列通常使用称为循环缓冲区的数据结构来实现。 The idea is that we maintain an array of elements, but pretend that the ends of the array are glued together to form a ring.这个想法是我们维护一个元素数组,但假装数组的末端粘在一起形成一个环。

From your debugging, it seems like the ArrayDeque internally maintains an array of 16 elements, which we can view like this:从您的调试来看, ArrayDeque似乎在内部维护了一个包含 16 个元素的数组,我们可以这样查看:

+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+

We maintain two different pointers, a head pointer and a tail pointer , keeping track of the position of the first element of the deque and the position one past the last element of the deque.我们维护两个不同的指针,一个头指针和一个尾指针,跟踪双端队列第一个元素的 position 和双端队列最后一个元素之后的 position。 Initially, they'll point to the start of the array:最初,它们将指向数组的开头:

 head
  |
  v
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
  ^
  |
 tail

Whenever we do an addFirst , we back up the head pointer by one step, then write the element to the location we find.每当我们执行addFirst时,我们都会将头指针后退一步,然后将元素写入我们找到的位置。 Since we're pretending that the two ends of the array are linked together, backing up one step here moves the head pointer to the last position:由于我们假装数组的两端链接在一起,因此在此处后退一步会将头指针移动到最后一个 position:

                                                             head
                                                              |
                                                              v
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |   | X |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
  ^
  |
 tail

To do an addLast , we write to the tail position, then advance it forward:要执行addLast ,我们写入尾部 position,然后向前推进:

                                                             head
                                                              |
                                                              v
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
| X |   |   |   |   |   |   |   |   |   |   |   |   |   |   | X |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
      ^
      |
     tail

Here's what it would look like if we did two more addFirst s:这是如果我们再执行两个addFirst的样子:

                                                     head
                                                      |
                                                      v
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
| X |   |   |   |   |   |   |   |   |   |   |   |   | X | X | X |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
      ^
      |
     tail

And here's what it would look like if we did two more addLast s:如果我们再执行两个addLast ,它会是这样的:

                                                     head
                                                      |
                                                      v
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
| X | X | X |   |   |   |   |   |   |   |   |   |   | X | X | X |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
              ^
              |
             tail

We read the elements of the deque by starting at the head pointer and proceeding forward until we reach the tail pointer.我们从头指针开始读取双端队列的元素,然后继续前进直到到达尾指针。 So in this case, we start reading from the slot pointed at by head , not the first position in the array.所以在这种情况下,我们从head指向的插槽开始读取,而不是数组中的第一个 position。

Eventually, the two pointers will meet in the middle.最终,两个指针会在中间相遇。 When that happens, we create a brand-new array that's larger than the original one (usually, 150% bigger), then copy the elements over into the new array to free up some space.当发生这种情况时,我们创建一个比原始数组大的全新数组(通常大 150%),然后将元素复制到新数组中以释放一些空间。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM