数据结构数组
This is the second post in my series Data Structures and Algorithms using JavaScript. Last week, I discussed Time Complexity, Space Complexity, and Big O Notation. This week I am going to talk about a very popular data structure that most programmers use on a daily basis, the Array. In this post, I will cover the Big O of common Array
actions (push
, pop
, etc) and we will also walk through the process of creating our very own Array data structure! Let’s get started.
这是我系列使用JavaScript的数据结构和算法系列的第二篇文章。 上周,我讨论了时间复杂度,空间复杂度和Big O符号 。 本周,我将讨论大多数程序员每天都使用的非常流行的数据结构Array 。 在这篇文章中,我将介绍常见的Array
操作( push
, pop
等)的“大O”,并且还将逐步完成创建自己的Array数据结构的过程! 让我们开始吧。
什么是数组? (What is an Array?)
A collection of multiple values that can be stored using a single variable
可以使用单个变量存储的多个值的集合
- The length can not be fixed (unless static) 长度不能固定(除非是静态的)
- The types of values can not be fixed 值的类型不能固定
- Can not use strings as an index to an element, must use an integer 不能使用字符串作为元素的索引,必须使用整数
静态与动态阵列 (Static vs Dynamic Arrays)
静态的 (Static)
Fixed in size
固定大小
动态 (Dynamic)
Copy and rebuild
Array
in new location with more memory, expands as you add elements在具有更多内存的新位置复制和重建
Array
,并在添加元素时扩展
常见阵列动作 (Common Array actions)
推O(1) (Push O(1))
Appends a new value at the end of an
Array
and returns the new length在
Array
末尾附加一个新值并返回新长度
Relies on the
length
property to know where to insert new values依靠
length
属性知道在哪里插入新值If
length
does not exist or can not be converted to a number,0
is used如果
length
不存在或不能转换为数字,则使用0
First, we use the const
keyword to create a new variable with the identifier jediCouncil
. The value assigned to jediCouncil
is an Array
of values that are of type string
.
首先,我们使用const
关键字创建一个标识符为jediCouncil
的新变量。 分配给jediCouncil
的值是string
类型的值的Array
。
Next, we call the push
method on the jediCouncil
Array
with a single argument anakin
.
接下来,我们称之为push
的方法jediCouncil
Array
与一个参数anakin
。
When we log our jediCouncil
on the next line, we see that the value anakin
is now the last value in our jediCouncil
Array
.
当我们登录我们的jediCouncil
下一行,我们将看到该值anakin
,现在是我们的最后一个值jediCouncil
Array
。
Since there is only one action taken and we don’t have to iterate through our Array
for this operation the Big O of the push
method is O(1)
.
由于仅执行一个操作,并且我们不必为此操作遍历Array
,因此push
方法的Big O为O(1)
。
流行乐O(1) (Pop O(1))
Removes the last value in
Array
and returns that value删除
Array
的最后一个值并返回该值
If you call on an empty
Array
,pop
returnsundefined
如果调用空
Array
,则pop
返回undefined
For this example, we want anakin
out of the jediCouncil
, we can use the pop
method for that:
在这个例子中,我们希望anakin
的出jediCouncil
,我们可以使用pop
该方法:
First, we use the const
keyword to create a new variable with the identifier jediCouncil
. The value assigned to jediCouncil
is an Array
of values that are of type string
.
首先,我们使用const
关键字创建一个标识符为jediCouncil
的新变量。 分配给jediCouncil
的值是string
类型的值的Array
。
Next, we call the pop
method on the jediCouncil
Array
, we do not need an argument when calling this method.
接下来,我们在jediCouncil
Array
上调用pop
方法,调用此方法时不需要参数。
Now, when we log our jediCouncil
on the next line, we should see that the value anakin
is no longer in our jediCouncil
Array
现在,当我们登录我们的jediCouncil
下一行,我们应该看到的是,价值anakin
不再是我们的jediCouncil
Array
Later, anakin
👋🏻
后来, anakin
👋🏻
Using pop
makes removing the last item from your Array
very quick and painless. Since this is the only operation that is performed, the Big O of the pop
method is O(1)
.
使用pop
可以非常快速,轻松地从Array
删除最后一项。 由于这是唯一执行的操作,因此pop
方法的Big O为O(1)
。
移位O(n) (Shift O(n))
Removes the first value in
Array
and returns that value删除
Array
的第一个值并返回该值
- Shifts the values and their indexes consecutively 连续移动值及其索引
First, we use the const
keyword to declare a new variable with the identifier jediCouncil
. The value assigned to jediCouncil
is an Array
of values that are of type string
.
首先,我们使用const
关键字声明标识符为jediCouncil
的新变量。 分配给jediCouncil
的值是string
类型的值的Array
。
Note: I am noting the index position of each value, this will help illustrate what
shift
does under the hood later注意:我注意到每个值的索引位置,这将有助于说明稍后进行的
shift
Next, I call the shift
method on our jediCouncil
variable.
接下来,我在jediCouncil
变量上调用shift
方法。
On the next line, I use console.log
to log the new value of jediCouncil
. Notice how the index positions have changed. Why is that?
在下一行,我使用console.log
记录jediCouncil
的新值。 注意索引位置如何变化。 这是为什么?
When shift
is called on our jediCouncil
Array
, the value yoda
is removed. Since this value was in index position 0
, we have to iterate through the Array
and update each value’s index position. This is why the shift
method has a Big O of O(n)
.
当shift
被称为我们的jediCouncil
Array
,该值yoda
被删除。 由于此值位于索引位置0
,因此我们必须遍历Array
并更新每个值的索引位置。 这就是为什么shift
方法具有O(n)
的Big O的原因。
Now we can see that yoda
has been removed and all of the other values in jediCouncil
have been shifted over to 1
less index position.
现在我们可以看到删除了yoda
并且jediCouncil
所有其他值都移到了少1
索引位置的位置。
接头O(n) (Splice O(n))
Remove, replace, or add new values to an
Array
删除,替换或向
Array
添加新值
First, we use the const
keyword to create a new variable with the identifier jediCouncil
. The value assigned to jediCouncil
is an Array
of values that are of type string
.
首先,我们使用const
关键字创建一个标识符为jediCouncil
的新变量。 分配给jediCouncil
的值是string
类型的值的Array
。
Next, we call the splice
method on the jediCouncil
Array
.
接下来,我们在jediCouncil
Array
上调用splice
方法。
Note: the
splice
method takes 3 arguments:注意:
splice
方法采用3个参数:
start
— this is the index you would like to start changing theArray
start
这是您要开始更改Array
的索引
deleteCount
— this is the number of values you would like to remove from theArray
(starting from thestart
argument)
deleteCount
—这是您要从Array
删除的值的数量 (从start
参数start
)
items
— this is the values you would like to add to theArray
, starting from thestart
argument
items
—这是您 要从start
参数 开始 添加到Array
的值If the
items
argument is empty, thespice
method will only remove items如果
items
参数为空,则spice
方法将仅删除项目
We pass 3 arguments to splice
:
我们将3个参数传递给splice
:
5
: we want to start changing thejediCouncil
Array
at index position5
5
:我们要在索引位置5
开始更改jediCouncil
Array
0
: we do not want to delete anything fromjediCouncil
; therefore, this value is0
0
:我们不想从jediCouncil
删除任何jediCouncil
; 因此,该值为0
”obi wan”
: this is the value we would like to add to index position5
”obi wan”
:这是我们要添加到索引位置5
When we log our jediCouncil
on the next line, we can see that obi wan
has been added to jediCouncil
in index position 5
; which, in this case, is the last position.
当我们在下一行登录jediCouncil
时,可以看到obi wan
已添加到jediCouncil
的索引位置5
; 在这种情况下,这是最后一个位置。
Welcome aboard, obi wan
👍🏻, I think you will fit in nicely
欢迎上船,ob带obi wan
,我想你会很合适的
Although we did not shift
any values or their index positions, we always take the worst case when determining Big O; therefore, the Big O of splice
is O(n)
尽管我们没有shift
任何值或它们的索引位置,但是在确定Big O时总是采用最坏的情况。 因此, splice
的大O为O(n)
让我们创建一个数组数据结构 (Let’s Create an Array Data Structure)
This section assumes you have some knowledge of how classes work for JavaScript. If classes are new for you, fear not! I will be writing a post on those in the near future. In the meantime, you can read more about them right here.
本部分假定您具有有关类如何用于JavaScript的知识。 如果您是新课程,请不要担心! 我将在不久的将来写一篇关于这些内容的文章。 同时,您可以在此处阅读有关它们的更多信息。
We know how the core pieces of an Array
work, so let’s build our own Array
data structure!
我们知道Array
的核心部分是如何工作的,因此让我们构建自己的Array
数据结构!
We start by using the class
keyword to create a new JavaScript class. We give our new class
the identifier MyOwnArray
.
我们首先使用class
关键字创建一个新JavaScript类。 我们给我们的新class
标识符MyOwnArray
。
建设者 (Constructor)
Inside of our MyOwnArray
class
we write our constructor
function. The constructor
is a method that is responsible for creating an object for that class
.
在MyOwnArray
class
我们编写了constructor
函数。 constructor
是负责为class
创建对象的方法。
We use the this
keyword to create and bind two fields to the scope of our MyOwnArray
class:
我们使用this
关键字创建两个字段并将其绑定到MyOwnArray
类的范围:
length
: anumber
that is initialized with the value of0
length
:一个以0
值初始化的number
data
: anobject
that is initialized with the value of an empty object{}
data
:一个object
是一个空对象的值初始化{}
推 (Push)
We create a method with the identifier push
that has a single parameter, item
. Keep in mind, this item
parameter can be any value that we want to append to our Array
. In our example, we are calling the push
method with the value ’phantom menace’
as the only argument (myOwnArray.push(‘phantom menace’)
).
我们使用标识符push
创建一个具有单个参数item
。 请记住,此item
参数可以是我们要附加到Array
任何值。 在我们的示例中,我们以值'phantom menace'
作为唯一参数( myOwnArray.push('phantom menace')
)调用push
方法。
Inside of our push
method, we assign a key-value pair for our data
field.
在push
方法内部,我们为data
字段分配一个键值对。
To assign the key value, we use the length
field value inside of bracket notation []
.
要分配键值,我们使用括号符号[]
内的length
字段值。
Next, we assign our value to item
接下来,我们将值分配给item
We increment the value of our length
field by 1
and return
the value of length
我们将length
字段的值增加1
并return
length
的值
Note: Did you notice that I incremented the
length
field in thisMyOwnArray
class? This explains why the last index position and your length always have a difference of1
注意:您是否注意到我增加了
MyOwnArray
类中的length
字段? 这解释了为什么最后一个索引位置和您的长度总是相差1
Let me show you an example:
让我给你看一个例子:
As you can see, we the starWarsMovies
Array
with 6 items. When we console.log
the length it returns 6
as we would expect. What happens when we try to retrieve the value at the 6th index position? We get undefined
. This is because we always increment our length
after we add an item to an Array
.
如您所见,我们的starWarsMovies
Array
具有6个项目。 当我们console.log
长度时,它返回6
正如我们所期望的那样。 当我们尝试在第6个索引位置检索值时会发生什么? 我们undefined
。 这是因为在将项目添加到Array
之后,我们总是会增加length
。
得到 (Get)
Next, we create a method with an identifier of get
. This method will be responsible for returning a value from our data
field.
接下来,我们创建一个带有get
标识符的方法。 此方法将负责从我们的data
字段返回一个值。
Our get
method has a single parameter, index
. Inside of our get
method, we use the index
parameter and bracket notation []
to return
that value from the data
field.
我们的get
方法只有一个参数index
。 在我们的get
方法内部,我们使用index
参数和方括号[]
从data
字段return
该值。
In our example, we want to retrieve the value that is index position 0
(myOwnArray.get(0)
)
在我们的示例中,我们想要检索索引位置0
( myOwnArray.get(0)
)的值。
流行音乐 (Pop)
Next, we create a method with the identifier pop
. As you might suspect, this method will be responsible for removing the last item in an Array
. This method takes no arguments.
接下来,我们创建一个标识符为pop
的方法。 您可能会怀疑,此方法将负责删除Array
的最后一项 。 此方法不带参数。
Inside of our pop
method we use the const
keyword to create a new variable with the identifier lastItem
. You can probably guess what we will use this for. We use bracket notation []
and the value of our length
field (decremented by one) to pull off the value of our last item in the data
field.
在我们的pop
方法内部,我们使用const
关键字创建一个标识符为lastItem
的新变量。 您可能会猜到我们将用它做什么。 我们使用括号符号[]
和length
字段的值(减1)来提取data
字段中最后一项的值。
Since data
is an object, we can use the delete
operator, followed by the property of the last item in our data
object to remove it.
由于data
是对象,因此我们可以使用delete
运算符,然后使用data
对象中最后一项的属性将其删除。
We want to make sure we decrement the value of our length
field by 1
, and then we return the value of lastItem
.
我们要确保将length
字段的值减1
,然后返回lastItem
的值。
综上所述 (In Summary)
I hope you found diving into how Array
s work in regards to their methods, Big O, and under the hood to be as illuminating as I did. Now we have a much stronger grasp on how we can harness the power of these important data structures. Next week I will be talking about Hash Tables. Can’t wait, see you then!
我希望您能从Array
的方法(Big O)中深入了解Array
的工作方式,并且能像我一样启发我。 现在,我们对如何利用这些重要数据结构的力量有了更深入的了解。 下周,我将讨论哈希表。 等不及了,再见!
翻译自: https://medium.com/dev-genius/the-array-data-structure-ca60d800372a
数据结构数组