数据结构数组和链表结构体
I have been going down a journey of learning some computer science since finished my Bootcamp. I think it is integral to know what you are using whilst writing your code. It is great to know when to use an array and when to use a hash table, two topics I have covered in previous blogs.
自完成Bootcamp以来,我一直在学习一些计算机科学。 我认为在编写代码时了解所使用的内容是必不可少的。 很高兴知道何时使用数组以及何时使用哈希表,这是我在之前的博客中介绍的两个主题。
With static arrays, we only have a certain amount of data or memory that can be allocated next to each other. However, dynamic arrays and static arrays can increase their memory and double up. However, doubling up an array will have a performance issue of O(n). We also remember insertion or deletion on an array for any element that is not the first or the last being O(n). Why? Well, we would need to loop through the rest of the elements after the insertion or deletion and moves the indexes.
对于静态数组,我们只能分配一定数量的数据或内存。 但是,动态数组和静态数组可以增加它们的内存并加倍。 但是,将数组加倍会产生O(n)的性能问题。 我们还记得不是第一个或最后一个不是O(n)的任何元素在数组上的插入或删除。 为什么? 好了,我们将需要在插入或删除之后循环遍历其余元素并移动索引。
Hash tables could store something wherever we wanted in memory, meaning we didn’t have to worry about insertion or deletion as we didn’t have to move around indexes, therefore having a Big O of O(1). However, the trade-off is…. hash tables are unordered!
哈希表可以在内存中的任何地方存储任何内容,这意味着我们不必担心插入或删除,因为我们不必在索引周围移动,因此具有O(1)的BigO。 但是,权衡是…。 哈希表是无序的!
So…. linked lists, where do they come in. Remember in the last blog, we said solving the issue of collision for hash tables could be resolved via linked lists.
所以…。 链接列表,它们从何而来。请记住,在上一个博客中,我们说解决哈希表冲突的问题可以通过链接列表来解决。
![Image for post](https://i-blog.csdnimg.cn/blog_migrate/b8b4c23424e857451d7787f103f34c22.png)
This table is used a lot for explaining hash tables in other articles, I saw it a lot especially when I was learning and researching hash tables myself… but no one really explained what happens post-collision (after the red number). It may be in another blog of theirs so I won’t judge! But I feel it is good to know what your data structure is doing even if you don’t need to use it. So let’s explain it.
在其他文章中,此表经常用于解释哈希表,尤其是在我自己学习和研究哈希表时,我经常看到该表……但没人能真正解释冲突后发生的情况(红色数字之后)。 可能在他们的另一个博客中,所以我不会判断! 但是我觉得知道您的数据结构在做什么是很好的,即使您不需要使用它。 因此,让我们解释一下。
Linked lists aren’t actually built into Javascript unless you build one yourself. They are more common in lower-level languages like Java where you also have to be aware of and manage your memory space/garbage collection! So what is a linked list?
除非您自己构建一个链接列表,否则它们实际上并没有内置到Javascript中。 它们在Java等低级语言中更为常见,在这些语言中,您还必须了解和管理内存空间/垃圾回收! 那么什么是链表?
As defined by geeksforgeeks ‘A linked list is a linear data structure, in which the elements are not stored at contiguous memory locations. The elements in a linked list are linked using pointers as shown in the below image:
正如geeksforgeeks所定义,“链表是一种线性数据结构,其中的元素未存储在连续的内存位置。 链接列表中的元素使用指针链接,如下图所示:
![Image for post](https://i-blog.csdnimg.cn/blog_migrate/ea67622490eec6557a2fdeb8e696c136.png)
In simple words, a linked list consists of nodes where each node contains a data field and a reference(link) to the next node in the list.’
简而言之,链接列表由节点组成,其中每个节点包含一个数据字段和到列表中下一个节点的引用(链接)。
We will discuss one of the two types of linked lists in this blog: singly-linked lists. We will discuss doubly-linked lists in the next blog.
我们将在此博客中讨论两种类型的链接列表之一:单链接列表。 我们将在下一个博客中讨论双向链接列表。
A singly linked list contains a set of nodes. Nodes are formed of two parts, the value (shown as data below) and a pointer.
单链列表包含一组节点。 节点由两部分组成,即值(如下数据所示)和指针。
![Image for post](https://i-blog.csdnimg.cn/blog_migrate/dbf5fd448ac0505ceba9e527561bace4.png)
The first node is called the head and the last node is called the tail. Linked lists are also called null-terminated, meaning the last node simply points to Null!
第一个节点称为头,最后一个节点称为尾。 链接列表也称为以空值结尾的,这意味着最后一个节点仅指向Null!
![Image for post](https://i-blog.csdnimg.cn/blog_migrate/120182f72289fb83af384f52dbfaea66.png)
A great visual learner that was brought to my attention thanks to Udemy and Master the Coding Interview: Data Structures and Algorithms is Visualgo. Have a play around with the hash tables, arrays and linked lists, it’s incredibly informative and interesting to watch a visual perspective of what is happening.
借助Udemy和Master of Coding Interview:数据结构和算法,我引起了我的注意,这是一个出色的视觉学习者,是Visualgo 。 玩弄哈希表,数组和链接列表,以可视的方式观察正在发生的事情是非常有意义的。
You may be wondering what the difference is between linked lists and arrays? A big difference is array elements are found next to each other in memory whereas linked list elements are scattered. Computers usually have a caching system which means reading from sequential memory faster than reading through scattered memory. So iterating through a linked list can be slower than iterating through an array even though they are both O(n)… however, insertion and deletion are a lot faster. Regarding, hash tables the one benefit linked-lists have is that although the data is scattered there is some form of order. If you look at the diagram above each node points to the next node. To give you a better understanding of the Big O — take a look at this table.
您可能想知道链接列表和数组之间的区别是什么? 最大的区别是数组元素在内存中彼此相邻,而链表元素则分散。 计算机通常具有缓存系统,这意味着从顺序内存中读取要比从分散内存中读取更快。 因此,即使它们都是O(n),通过链表进行迭代也比通过数组进行迭代要慢。但是,插入和删除要快得多。 关于哈希表,链表的一个好处是,尽管数据分散,但存在某种形式的顺序。 如果您查看上面的图,则每个节点都指向下一个节点。 为了让您更好地了解Big O,请查看此表。
![Image for post](https://i-blog.csdnimg.cn/blog_migrate/f7d68d04510a4de288274b3e71bd954a.png)
Now you may be looking at the deletion of a singly linked list and wondering why it is O(1)… There is a very good discussion on stack overflow here → https://stackoverflow.com/questions/14048143/why-is-deleting-in-a-single-linked-list-o1.
现在您可能正在查看单个链接列表的删除,并想知道为什么它是O(1)…在这里有关于堆栈溢出的很好讨论→ https://stackoverflow.com/questions/14048143/why-is-删除单个链接列表o1 。
Let’s move onto the next part of learning about linked lists. The pointer! Or in the diagram earlier, the arrow.
让我们继续学习链接列表的下一部分。 指针! 或在前面的图中,箭头。
![Image for post](https://i-blog.csdnimg.cn/blog_migrate/4d8132cbb69a30015b1ced7b671b1900.png)
I have created a pointer here. mySecondFavouriteObject has a reference to an object. So the pointer is the reference to the memory space. We aren’t copying myFavouriteObject into another space in memory. When we look at our RAM, there is only one entry for {name: “JimBob”}. Both myFavouriteObject and mySecondFavouriteObject point to {name: “JimBob”}. If you don’t fully understand that, don’t worry, use the visual below.
我在这里创建了一个指针。 mySecondFavouriteObject具有对对象的引用。 因此,指针是对内存空间的引用。 我们不会将myFavouriteObject复制到内存中的另一个空间。 当我们查看RAM时,{名称:“ JimBob”}只有一个条目。 myFavouriteObject和mySecondFavouriteObject都指向{name:“ JimBob”}。 如果您不完全了解这一点,请不要担心,请使用下面的视觉效果。
![Image for post](https://i-blog.csdnimg.cn/blog_migrate/ee58807fbaaf028e98241a7f7450769f.png)
Okay, so this returns { name: ‘Jimbob’ } with the number 1 or 2 after it… what does this prove? Well, follow the next code snippet below to confirm that both objects simply point to the same { name: ‘Jimbob’ } in memory.
好的,因此返回{名称:'Jimbob'},其后是数字1或2。这证明了什么? 好吧,请按照下面的下一个代码片段确认两个对象只是指向内存中相同的{name:'Jimbob'}。
![Image for post](https://i-blog.csdnimg.cn/blog_migrate/52c036f43a93cb433415b0c879f89d92.png)
The name changes for both! It works if you also change mySecondFavouriteObject.name instead.
两者的名称都改变了! 如果您还更改了mySecondFavouriteObject.name,它将起作用。
One final test, let’s delete myFavouriteObject and see if mySecondFavouriteObject still retains the key/value pairing.
最后一项测试,让我们删除myFavouriteObject,看看mySecondFavouriteObject是否仍然保留键/值对。
![Image for post](https://i-blog.csdnimg.cn/blog_migrate/fc092bc5b6d223d545676b42d66cef9b.png)
It should still keep the reference!
它仍然应该保留参考!
This should give you a better understanding of how a single linked-list works.
这应该使您更好地了解单个链表的工作方式。
Next, building your own linked-list in Javascript. So we understand the concept of what a single linked-list should be, but how do we design one, with a basic append and prepend.
接下来,用Javascript建立自己的链表。 因此,我们了解单个链接列表应该是什么的概念,但是我们如何设计一个带有基本追加和前缀的列表。
Well firstly, we would need to create the beginning of the linked list which is the head node (which would also be the tail node for the first data entry).
首先,我们需要创建链表的开头,即头节点(也将是第一个数据条目的尾节点)。
![Image for post](https://i-blog.csdnimg.cn/blog_migrate/c8484bab8ff8cb03748fa3473cee5bd1.png)
So, this should be fairly self-explanatory. But we are passing our class linkedList a value, the constructor creates the first node using the value being passed in, it’s pointer (next) is then set to null as the end of a single linked-list must point to null.
因此,这应该是不言而喻的。 但是我们给我们的类LinkedList传递了一个值,构造函数使用传入的值创建了第一个节点,然后将其指针(下一个)设置为null,因为单个链表的结尾必须指向null。
Now we have the beginning of a linked-list let’s create an append and prepend method.
现在我们有了链表的开头,让我们创建一个append和prepend方法。
![Image for post](https://miro.medium.com/max/9999/1*3Rf2AgVdoXt1Ap_1_juLMw.png)
A lot is going on here but it is all fairly standard method and class stuff. We simply create a method function called append which takes a value. This is used to create a new node that will be at the end of our single linked-list, therefore we know this node must point to null.
这里有很多事情要做,但这都是相当标准的方法和类的东西。 我们只需创建一个名为append的方法函数即可,该函数需要一个值。 这用于创建一个新节点,该节点将位于单个链接列表的末尾,因此我们知道该节点必须指向null。
We then set our current last node to point to the newNode being made and make our newNode the tail!
然后,我们将当前的最后一个节点设置为指向要创建的newNode并将newNode设置为尾部!
See if you can figure out the prepend method as it’s fairly similar!
看看是否可以弄清楚prepend方法,因为它非常相似!
![Image for post](https://i-blog.csdnimg.cn/blog_migrate/4adc8e838853075593f0c99c4effa5a0.png)
The only real difference here is that our next value needs to be set to the current head node before we change our newNode to the head of the linked-list!
唯一真正的区别是,我们需要将下一个值设置为当前的头节点,然后再将newNode更改为链表的头!
I haven’t done insertion or deletion, but have a go at those yourself. I learned the majority of this knowledge via Udemy and the Master the Coding Interview. Truly is a great breakdown of everything.
我尚未完成插入或删除操作,但您自己可以尝试一下。 我通过Udemy和Master of Coding Interview学习了大部分的知识。 确实,一切都是重大故障。
翻译自: https://medium.com/swlh/data-structure-and-linked-lists-3a539856af5b
数据结构数组和链表结构体