您不了解区块链,除非您了解这种简单的数据结构
区块链是一个不变的,有序的,反向链接的交易区块列表。 如果您想真正了解区块链,则需要了解链表。
链接列表是数据元素的线性集合。 链表中的线性度不是由每个元素的物理位置定义的。 相反,链表中的每个数据节点都指向链表中的一个或两个其他节点。
使用[1、2、3]这样的数组,您知道元素1在位置[0],元素2在位置[1]。
每个元素的物理位置定义了数组的线性。 链接列表不会发生这种情况。
节点组成链表中的元素。 每个节点都有一个数据节。 除数据外,每个节点还有一个“前进”和“后退”部分,指向列表中的上一个和下一个节点。
在数组中,如果要在[0]处插入项目,则需要将数组1中的每个元素向右移动以在[0]处留出空间。
使用链接列表,您可以在列表中的任何位置插入数据项,而不必移动整个列表。 为此,您必须告诉下一个和上一个节点指向该新节点。
假设您有一个每天都在增长的数组。 一天,数组中有5000个元素。 要在[0]处插入项目,您必须移动5000个元素。
使用链接列表,您不必移动任何项目,您可以插入它们。 这使得它们对于列表可能会快速增长的列表很有用。
链接列表具有可伸缩性和适应性。
我们称节点的“向前”和“向后”元素为该节点的指针。 节点中有2/3个元素,具体取决于它是单链列表还是双链列表。
单链表
单链接列表具有一个数据元素和一个指向下一个节点的指针。 当指针指向无物时,我们说它指向Null。
2个组件组成了单链列表节点-数据和指针。
单链接列表不能向后指向,因为它们没有“向后”指针。
指针除了下一个节点的位置以外,不存储其他任何数据。 它实际上是一个指针。
添加了一个新节点,以显示其中包含多个节点的单链接列表的外观。
根据实现的不同,链表也可以有2个特殊的指针-头和尾。
头指针指向链接列表中的第一个节点。 尾指针指向链接列表中的最后一个节点。
如果链表中只有一个节点,则约定是头指向该节点,尾指向空。 尽管这完全由程序员决定,并且在某些情况下头和尾可以指向同一奇异节点。
程序员为链接列表创建特殊功能以使其可用。 这些功能是:
- node.data =从当前节点获取数据
- node.next =转到下一个节点
双链表
双链列表是具有“向后”组件的单链列表。
双向链表中的每个节点都有3个组成部分 。 向后指针,数据元素和向前指针。
与单链列表一样,双链列表也具有特殊功能。 这些功能是:
- node.data =从当前节点获取数据
- node.next =转到下一个节点
- node.prev =转到上一个节点
如果在头节点上使用node.prev,则该函数将错误或生成NULL值。 如果在尾节点上使用node.next,则该函数将错误或产生NULL值。
遍历链接列表
我们想对链表做很多事情就是遍历它们。 向上和向下链接列表。
我们需要做的第一件事是定义我们的起点。 好吧,链接列表(头)的起点是个好地方。
现在我们想要一个遍历整个列表的循环。 我们要遍历每个节点,直到在Python中当前选择的节点为“ NULL”或“ None”为止。 一旦我们碰到“无”节点,我们就知道我们已经结束了。
现在,我们想在遍历链接列表时对其进行处理。 让我们打印链接列表中每个节点中的每个数据元素。
现在要实际移至下一个节点,我们使用node.next函数:
的符号:
之所以称为圆点表示法,是因为我们将链接列表的功能称为“下一个”。 我们将很快看到如何对链表进行编程。
搜索和遍历链表的时间复杂度为O(n)。 如果您不理解O表示法,我强烈建议您阅读这篇文章:
编程链接列表
大多数语言都没有链接列表,因此我们必须自己编程。
因为节点将具有相同的功能,并且在我们的链表中看起来相同,所以最好将其创建为类。
类是对象的模板。 您可以从一个类创建许多对象。
让我们用Java设计链表。
您可以使用点表示法将3种方法应用于此节点:
该类具有“构造函数”方法,该方法在每次创建新节点时都运行。 这为我们初始化了节点。 构造方法将下一个和上一个指针设置为指向“ null”。 然后将数据设置为“ i”,这是用户想要放入节点的内容。
如果我们要制作一个节点,则只需编写以下代码:
这将创建Node类的实例 ,并为其提供数字“ 5”作为该节点的数据元素。
现在,当然只有一个奇异节点根本没有用。 我们希望将更多节点添加到链接列表。
还记得以前的示例,其中向数组的前面添加元素需要将每个元素向右移1吗?
我们将展示如何使用链接列表更轻松地完成此操作。
为了将新节点添加到列表的最前面,我们需要一个执行此操作的方法(函数)
在将节点添加到最前面之前,首先必须创建一个具有所需值的节点:
现在,根据我们之前对节点类的定义,节点的功能node.next和node.prev指向null。 让我们更改一下:
我们尚未更新头指针,因此它仍指向链表的头,这就是我们要在链表中创建第二个节点的位置。 我们使node.next指针指向头指针所指向的位置。
因为我们要在链表的最前面插入一个新节点,所以我们需要尽快更新头指针。 首先,我们将定义先前指针指向的新节点的位置。
实际上,我们不需要将newNode.prev更新为null,因为它已经在Node类中完成。 但是,为了使事情更清楚,代码已放在此处。
现在我们需要更新第二个节点,即头指针仍指向的节点。 它需要知道node.previous现在指向一个实际节点,而不仅仅是空。
如果头指针没有指向任何东西,因为还没有创建链表,那么我们就不需要更新节点。
如果头指针指向一个节点,则通知该节点.prev函数指向我们刚刚插入的新节点。
否则,如果头部不指向任何物体,则将尾部作为newNode。 前面我们讨论了奇异节点是否有指向它的头或尾指针。 这是程序员决定的部分。 在这里,我们选择使单个节点同时位于尾部和头部。
现在,我们只需要更新标题指针即可指向链接列表的新标题:
我们也可以用类似的方式删除链表前面的节点:
我们在这里假设curr是一个指向链接列表中任何节点的指针。
然后,我们要设置curr为head,因为我们要删除head节点:
我们要确保头部指向某物。 curr不等于null,因为那里有一个节点。
我们将头指针1向右移动。
我们还将head.prev设置为null。
现在我们删除curr.next的指针
现在,我们有这个节点坐在一个无所事事的空间中。 如果要对节点做其他事情,我们将返回该节点。
就是这样! 该节点不再连接到链表,因此被“删除”。
将项目插入链接列表
链表的真正功能是能够在其中的任何位置插入项目。
在链接列表中的任何位置插入项目类似于在头部插入项目。 您只需要更改几个变量,想法还是一样。
每当我们想要插入一个新节点时,我们只需告诉该节点下一个和上一个节点是什么。
搜索链接列表
链接列表通常是排序的。 可以将项目插入链接列表中的任何位置,因此将它们放在正确的位置很有意义。 如果您有一个链表,其数据为3、4、6,则程序员可能会将包含5的新节点放在4至6之间。但这完全取决于程序员。
我们可以使用二进制搜索来搜索列表。 但是,这是一个坏主意。 我们不知道链接列表的中间位置。 每次我们想要找到中间节点时,我们都必须计算列表中的每个节点,然后将其计数一半。
我们可以使用顺序搜索的修改版本来搜索链接列表。
假定链接列表按升序排序。 我们可以使用这些信息来加快顺序搜索的速度。
由于链表是按顺序排序的,因此我们知道链表中的节点以某种顺序排列,例如1、2、3、4、5。 如果node.data大于键(我们要查找的键),我们知道它不在列表中,因为它已排序。
因此,如果我们想找到2.5,我们可以这样做:
1 is selected
is 1 goal? - no
is 1 > 2.5? no
2 is selected
is 2 goal? no
is 2 > 2.5? no
3 is selected
is 3 goal? no
is 3 > 2.5? yes - we can assume 2.5 is not in list and thus end the search here
有很多搜索算法。 但是大多数时候,如果您了解有关数据的一些信息,则可以更改搜索算法以提高效率。 通常,二进制搜索非常有效,但是效果不是很好。 不要使用算法,因为Stack Overflow表示这是最快,最好的算法。
算法就像编程语言。 我们都有自己的最爱,有时我们会说一种编程语言胜于另一种(Python,我爱你)。 但总而言之,说一种编程语言比所有其他语言都要好是愚蠢和天真的。 使用正确的工具进行作业,并根据需要进行更改!
区块链
回到区块链技术。 之前我说过:
区块链是一个不变的,有序的,反向链接的交易区块列表。
因此,让我们开始吧。
区块链是不可变的。 从理论上讲,您不能更改区块链。 有可能,但是很难做到,特别是对于像比特币的区块链这样的区块链。
就最频繁的交易而言,区块链是按顺序排列的,位于链的“顶部”。 或最频繁的交易最右边。
区块链被“反向”链接,指向链中的前一个区块。 每个块均指代其后面的块。
每个块都是一个事务。
您现在应该对链接列表及其工作原理有深刻的了解。 您还应该了解区块链的链表部分。