00:00
呃,基础的这个存储数据结构叫make克尔帕特下述对吧?那其实我们最重要的一个内容其实就是这个内容,克尔帕特里下树这一部分,可能相对来讲,大家如果看课件的话,或许还没那么枯燥,我我我觉得啊,当然也有可能我的课件你做的很枯燥,大家听时也会想睡觉,但是我觉得至少比那个那么多公式看起来好看一点,对吧,即使是大段文字也比公式好看好。那么我们前面提到了这个梅克尔帕的比赛树,然后他的英文名字大家大家就是看一下,见到之后知道就可以,他叫什么呢?就是默克尔,所以大家看到有些地方会叫他默克尔树,对吧?啊,那个什么德国总理默克尔就就是这个名,所以有些地方翻译叫梅克尔,有些地方叫默克尔,然后后面这个叫帕特里夏,一般翻译都是叫帕特里夏。也有可能翻译成帕特里亚或者什么的,这个大家知道是什么就可以了,然后它的这个简称一般就是MPT,然后后面的这个tree,有时候大家可能会发现它会写成TE那种形式,那个TE一般情况它是一个,就是后面我们会说到它是一个字典数的一个一个简写,所以就是大家就看到所有的这些写法,它都表示一个东西就可以了,这因为大家没有统一的定义,所以就是很多东西可能还是相对比较乱,这个东西我我猜啊,就是大家如果要去面试的时候,如果要是说自己想做底层链的话,比方说大家之前学了这个呃,比特币,然后自己写了这个构构成去开发一个自己的区块链,对吧,然后出去之后可能跟别人说我对底层很了解,那有可能别人就会啊,首先可能会问你,比方说这个pow到底怎么回事,对吧,这些肯定会问,那有可能就会问你底层数据结构。
01:49
啊,那比特比特币的话,你说懂,那肯定会问你梅克尔树了,如果你说以太坊我底层也很懂,那别人很有可能就会问你梅克尔帕特里下树,所以我觉得这个可能还是比较有用的一个东西,至少就是出去跟人说也是也是有用的啊好吧,那说了这么多,我们先来说一下到底是什么玩意儿,哎呀,这个这个一看这种定义,这就又比较烦了啊,还是先过一下吧哈,呃,首先就是它的定就是这个名称啊,翻译一般翻译成梅法尔派底下说,然后。
02:24
这是这其实没有说它定义啊,这先说了它的一些特点,这个MPT它主要是干了什么事情呢?它主要是提供了一个基于密码学验证的底层数据结构,为什么说基于密码学验证的?大家学过梅克尔树应该就知道,梅克尔树它是能够做这种哈希校验的,对吧?所以这其实就是梅克尔树的一个特点,然后它的目的是用来存储剑池,对关系,那这个好像就跟梅克尔数有点不一样了,对吧?因为梅克尔数大家之前学的时候应该他存的就是哈希对吧,所有的哈希然后两两放在一起,然后这个再算一个负哈希,一个一个把它算上去,这是梅克尔数的特点,那那这里边。
03:13
就是MTT,它不光要存哈希,它还要存储键值对关系,那它是怎么做到的呢?那肯定这个就跟后边这个所谓的帕以下数有关了,那等一下我们来详细的讲啊,然后再看它另外一个特点就是MTT,它是完全确定性的,这是什么意思呢?就是在一颗。梅克尔特里在树上面,它的一组键值对它的存储的位置是唯一确定的。什么意思?就是说你如果要去,就是根据一个某一个K去找一个内容的话,那绝对找出来都是一样的,它是唯一的,一定只能在那个位置存储,而且就是整个它的数结构也不会变化。你怎么样去寻找,每次的路径也都是这样的,就除非当然就是除非你做了更改,对吧,更改之后有可能会变化,但如果说在正常的一个状态下,每次访问都是一样的,呃,而且就是说每一次访问大家都能够找到同样的哈希,跟哈希都是一样,所以这也是有梅克尔树的这个特性在里面啊,这里大家这么去说的话,大家可能觉得还是有一点泛泛而谈,好,那接下来我们再说一个特点啊,就是说它的性能方面的特点,它的性能。
04:31
那我们一提到这个基本的数据结构,就会提到特别像数结构,那就会说它的插入时间复杂度是多少呢?查找时间复杂度是多少呢?对吧?删除它的这些操作,所谓的增增删改查对吧?这里边的插入查找删除是啊,我这里写错了,不是实践复杂度啊,时间复杂度。时间复杂度啊,都是啊,这个大的这个大家应该见过这种写法对吧?是表示什么呢?就是表示如果大家来的这个量级,就是说我要去查找,查找多少次,这个N是表示这个量级数量操作的数量对吧?N假如说是这个操作的量级的话,那么。
05:25
要多少次它能够把,就是它对应的这个时间是用多少次查找能把它查出来。对吧,是这样的一个一个一个要求,那大家可以看到它一般情况这个复杂度是什么呢?是log n,那log n其实就是N在取对数,对吧,取常用对数,那这个其实就是说对于100而言,取对数之后就变成了十,所以大家可以想象得到,就是你对于一个就是呃,正常来讲它它复杂度是一个100的这样的一个一个数量的话,它只需要十次就可以把它找出来,那这个其实是就是非常非常的一个性能了,对吧?所以可以看到MTT它的十性能上是很好的,而且它有一个特点,就是相对于其他性能很好的树结构,比如说红黑树MPT呢,它更容易理解,而且代码上也更容易实现。
06:27
好,那接下来我们就看看它到底是怎么容易理解,然后这个代码上,我们到时候这个打开源码也去看一看它到底怎么容易实现,好,前面这一块还是比较比较烦啊,那我们接下来就给大家一点相对好理解的东西,我们从什么东西先说起呢?先从字典数说起。这个字典数就是大家应该对这个比较熟悉了是吧?呃,这个典数一般情况英文就写成这个tree来看到这个T一般就是叫字典数,它还有一个名称叫前缀数prex。
07:05
那这个数是一种什么样的东西呢?它是属于一种搜索数,是一种有序的数,数据结构,呃,然后呢,它用于存储动态的集合或者映射,然后它的P通常都是字符串啊说了这么多,这这到底什么玩意儿啊,来吧,看这个图,来看它这个存储是什么样的一个存储方式啊,大家看最上面这就是一个根节点对吧?根节点然后往下去,一个箭头分出来,一个箭头分出来,一个箭头分出来,这个数就分叉了对吧?分了各种各样的这个树枝出来。然后大家看它的这个子节点呢,里边存了一个T。然后这边就存了一个大A,这边存了一个I,所以大家可以看到,根据这个。就是这里的这个存储内容的不同,相当于我们在查找的时候就应该进入不同的分支去,对吧,如果查T的话就到这边来,A就到这边来,I就到这边来,对吧,肯定是这样的一个结构,那接下来大家继续看,然后T这里呢,又有1O作为它的一个路径,然后它指向的这一个节点里边存着是to,所以大家看到。
08:28
所以最后的这一个,呃,节点里边大家就会看到它的存储的,下面这个大家可以认为是它存真正存储的值,就是真正上面这个呢,其实只是它的路径,那路径其实就是它的K对不对?所以大家看到这里其实就代表了一个key是to。然后直是七的一个建持队啊,那为什么叫字典数,就是因为它的K是按照字典去排列的,根据字典去像查字典一样,就能把它对应的那个值查出来,这就叫字典数,那大家再看一下这里面还存了哪些东西?
09:11
比方说这里,这里一个大A,然后15,那这个简单对吧,那就是代表我们这个数结构里边存了一个建设,对叫做大A15K是大A,值是15。那这边这个呢,啊,这边这个中间就有一个11,那说明K是小I,然后值是11对吧?那其他的呢,这里这个五代表什么?五是一个value对吧?那它的K是什么?对in对吧?In这个K就代表它的值是五,那同样它还能再往下继续走。In,这个in是那种应该是小小客店小客栈的那个意思,对吧?In,这个in它的值是酒。
10:00
那同样大家可以在这边看到啊,T这边分叉出来一个T,这个T没有存东西,但是T又分叉了,然后就可以看到有T茶叶,有T的有ten,那么T的值是三,T的值是四,Ten的值是12。所以这就是这个字典数,那大家可以想一下,呃,就是我们是不是在如果让大家去设计一个像以太坊这样的复杂的一套数据存储的系统的话,大家觉得应该把它里面的状态怎么去存。有些同学可能说啊,你那里边那么多账户嘛,一个一个存嘛,顺序存,存完一个存一个,存完一个存一个对吧?啊,那这个肯定是不行的,那我们知道里边因为它是变长的,对吧?啊,那大家就知道我们既然你里边变长的,那我里边存了一个根,它在哈希出去就可以了,那我本身的账户是不是还可以一个一个顺序存呢。
11:03
顺序存有什么问题啊,太难找了,对吧,刚才有同学说的很好啊,如果你去顺顺序存我们的账户的话,那你是不是找这个账户的时候,你得。从头完全把它便利一遍,对吧?我们以太坊里面找账户那么多,你每次查一个账户都去便利,这简直要人命啊啊,那有同学就说了,那账户你不是本来也是一串字符吗?我把它直接排序,那不也就行了吗?那你每次插进来一个新账户的时候,那可都得重新排序。对吧,你这个就是大家知道的,就是如果你作为一个顺序存储的话,如果把它排序,那你查找是方便了,但是插入和删除,删除可能还好啊,后续你就把它直接让删除就可以了,对吧?后续直接顶上插入就会比较麻烦,你同样可以找到它的位置,然后插进去,后面都得往后移,所以大家可以看到数结构去做这样的存储其实是最方便的一种方式,所以很多这个数据库的底层系统实现的时候都是用的数结构,大家可以想就是那我们的这一套不太好地址,然后对应有一套它的状态,大家存的时候拿什么去存呢?
12:22
对,大家想到它的K是哈希对吧,哈希本身就是一串字符串。那所以很自然的一个想法就是,那我们是不是可以用字典数据存在,所以这其实就是最初的一个想法,这也是就是LV一开始对这个的一个最初的一个构想,一个一个构建,但是字典数还远远远远不够,大家可能觉得诶这个查字典这这方式好啊,但是纯粹你很简单的用查字典的这个方式去做呢,大家可以想象一下,我如果要分差的话,应该分多少差。
13:04
二叉一条,对,那应该是只要自己你符合这个字典,就是我的这个字符集的字符都应该分一个叉,对吧,得按道理是这样的,那所以说呃,如果要是基本的用这种方式去存存储的话,我们可以先这么想,那我们就定义一个整个的这个字符串,字符集,然后我每一个节点都分这么多,分这么多差,如果是这里我们这个英文的话,英文单词的话。就像我们自己的字典一样,它是会分多少叉,分26个叉对吧?对,就是我最初的这个根,根节点,根目录直接分26个查,你是A打头的去A类查询分支去查,B打头的去B这里去查,C打头去C啊那当然了,如果大家想到纯粹英文字母的话,你首先就是大小写,那还那还不一样的对吧,那这就是首先就52个了,另外你还允许不允许数字呢,要有数字呢,再加十个,那就62个,所以这个其实还是要分差分的挺多的,呃,那呃,继续的另外的一个考量,就是说大家可以看到,比方说我们这里边的这个这个。
14:19
呃,爱到一直到印到下面的这个印啊,它这个一串路径里边,其实好像到最后它只是一条路径,对吧,其实没有分叉,没有分出来,那是不是前面这里I是不是就没有必要把其他的abcd全全分出来,全占用这个空间呢?这也是一个考量,就我我们是不是能把它做一个压缩,这是另外一种考量的这个角度,那当然了,就是在这个以太坊的数据结构里面,就还有一些别的优化的一些考量。那这里就再给大家介绍一个,这里相当于是前序的一些知识啊,还有一种数结构叫做奇奇数数ready ready。
15:05
那这个数呢,它还有另外一个名叫压缩前缀数啊,奇数数可能听起来有点有点烈扭,不知道他说什么压缩前缀数这个就听起来很明确了,对吧?那是什么意思呢?大家对比前面的四点数字,点数叫前缀数。所以就是我按照这个字典序的一个单词作为K,然后把它的这个一个一个前缀提取出来,当成我的pass寻找的这个取值的pass,所以呢,它就叫做前缀数,那我们这里的奇数数,它叫压缩前缀数,什么意思呢?就是说它的这个pass,它的这个路径前缀可以压缩。具体的定义是什么?它是说一种空间优化之后的子点数。什么意思呢?如果一个节点只有唯一的子节点,那么这个子节点就会与父节点合并存出。
16:08
啊,观看定义也是比较复杂,那大家看一下这个图吧,这这两个图都是直接在wiki上扒下来的图啊,然后很多文章里面也会去去引用这两个图比较算是比较经典的图了,大家看一下这个压缩前缀数或者说积蓄数,它到底是怎么样的一种存储方式,那么首先大家看到还是有一个根,那根这里代表的路径是一个R。然后跟字典数一样,按照字典去向下去分叉,然后去寻找对吧,那么它这里就大家看到接下来它就不仅仅是一个O一个M这样分了,它直接就OM合在一起了,为什么呢?因为它需要存储的,大家可以看到就是它这里要存储的列出来的这个1234567,就是需要存储的K,对吧?然后1234567,这是它要存储的值,这里它不是k value,这是value k这样一个方式啊,那大家可以看到要存的这个K呢。
17:12
如果前面我们从R分叉开来,R第一个都一样,这没问题,之后要存的时候,大家会发现一个O,一个U。那是不是我们其实应该就是直接分O和U2个叉就可以,然后再往后大家发现O后面的就全是M,继续往后走对吧,U后面的就全是B继续往后走,那这两个其实O跟U根本就没有分叉对吧?哦,对不起啊。O跟U根本就没有分叉,它直接就有一个直系的子节点跟到后边了,所以大家就会发现,那我们为什么还要用两个步骤,就是把它当成两个层级来存储呢?
18:02
我们直接把它合并起来不就完了吗?所以就有了这种存储的方式,就是直接之后你只要是相同的东西,我全部分叉全放在里边。只有它分叉开的地方,我才才会把它分开,再去做一个存储,那大家就可以看到R下来之后的分叉,直接就是一个是OM,一个是UB,确实就只有这两种情况,对吧?好,那接下来OM的这一只M之后就有分叉了。有A有U,所以就一只是A,一直是U,然后我们每一个再单独去看A,这一只呢,A后面都是N,没分叉。所以说把N合并在A这里,直接就是an。N后面再看一个是E,一个是U,那这个不能合并了,继续分叉,所以它下面的这个存储就是an存储在一起之后再去分叉的时候,一个是E,一个是U,然后U下面呢,啊一个E这边就没了,那U下面都是,那U和S也合并在一起。
19:13
啊啊,大家会发现这里不是啊,是这里已经是N后面分出来的U了,对吧,跟下面这个没关系对吧,所以它只有这个us了,所以说就直接就到这里。刚才我的描述里边可能用了存储这个这个词,但是事实上在这个过程当中,大家可以认为这里它存是存了一个东西的,但是这个存的并不是我们要找的值,要找的value,对吧,这里存的其实是。其实是K的一部分对吧,所以大家注意啊,这里存储的是K的路径。那我们如果要找Roman,呃,这是什么?Roman Roman Roman,好吧,我也不知道这个单词什么意思啊,我们要查这个词的时候,怎么样去找呢?那就从R出发。
20:06
然后向下找O,直接就到OM,那继续向下找,后面是A,直接就是an。然后再向下找是E,就到这里查到它的指是E,所以是这样一种便利的过程,那同样的道理,大家就可以看到我前面分叉的地方,An这里是这个A这支分叉开,那U那支呢,后面就没有别的分叉了,只有ulus一路下去对吧,没有别的单词了,所以所有的全存在一起,它直接就对应节点三,呃,就它接就对应三这个值。所以这个节点的K是前面这个romulus,然后直是三分啊,同样大家可以看到从这边走啊,这边runs,所以大家可以看到这是romance。对应的值是四,然后这边是一个robber,对应的是五啊,所以就是这样,大家可以看到跟字典数的查询方式完全一样,只不过呢,就是我们把只要你在一个路径上,前后只是一条没分叉的地方全给你合起来啊,这就是压缩前缀数,好呃,那说了这个之后大家就会想到,诶,这个看起来就比字点数又优化了一些,对吧,空间上利用就会更高一点。
21:29
啊,那这个东西是不是就可以作为我们存储的一个数据结构呢。呃,其实是的,其实在一开始雏形其实就是从字典数到奇数数,呃,在这个微神对于以太坊的底层设计构想里边,就是拿奇数数作为一个基础的数据结构来做存储的,但是呢,奇数数又会觉得可能会有各种各样的问题,那他会有什么样的问题呢?我们先来看一个,就是他对这个奇数数的一个底层数据结构的一个描述啊,大家前面是看的,就是说哎,我们这么看的话很简单啊,这个里边存R,这个里边放OM,放UB,那本身它的这个节点。
22:16
它的组成,它的数结构定义应该定义成一个什么类型呢?难道是一个变长的变长的这个类型吗?那好像有点问题对吧?变长类型的话,我们定义的时候都要用哈希这种映射的方式去定义的,那你这里按道理我们如果存在数结构里边的话,它应该是定场的,要不然你都不知道给他分配多少空间嘛。所以大家看一下,正常来讲,奇数数或者是字点数,它的一个标准的存储方式是什么样呢?它的一个标准节点存储的数据是这样一个模式啊,这这就又有点有点枯燥了啊,是什么样的呢?用N来表示II用I来表示I0 I1 I2 I3,一直到in。
23:05
最后带一个value。这什么意思?一个节点里面,它的数据的这个类型,或者说它的这个存储数据的这个方式是这样的,所以它是一个数组,对吧。他为什么是个数组的。存储对,简单说的话就是要存储路径,但是你路径有可能分叉呀,所以其实就是我们第一节课说的字典数,想要去真正存储的时候,那你正常就应该把要分叉的这些都列出来,对吧。那对于一个字点数来说,我不知道要分差多少,那我就应该把我所有的字符集全列出来,全放到这里,对吧?所以大家可以看到I0到in,它表示什么呢?表示的是定义我们定义好的一个字母表当中的字符。
24:02
简单说就是这就代表什么,对于英文单词来讲,这就代表ABCDEFG,一直到Z。所有的字符在这里对应一个位置。然后这个位置里边。我可以去存。它指向的下一个分支节点的。地址。所以你如果寻找的时候,大家可以想象一下我怎么寻找啊,啊,所以大家想象一下,为什么我前面说我不应该说里边,我们这里边存了这个R,存了OM,所以它的这个寻址方式是什么呢。是我这里假如是A的话。这里是A,第一个是A,第二个是B的话,我这里并不是存A存B的,而是我已经定义好了,第一个它的角标就叫A。第二个它的角标就叫B,然后我去访问的时候,假如我要查一个词Apple,它是A打头,那我直接就到它第一个存储位置去找。
25:08
那那你就存着Apple。A打头的这一分之它去存到的那颗子树,就可以找到那颗子树的根节点,所以是这样一种存储方式。但是这个感觉能理解吗?稍微有点绕是吧,然后这里边呢,我们如果要是从零到N的话,那这个字母表其实就一共有N加一个字符了,对吧?那所以这里边为什么它又叫奇数数呢。这样,这个N加一就可以叫做这个数的奇数。它的每个节点都有这么多种分支的可能,都有N加一个分支的可能,所以它就叫做奇数数,就N加一的以N加一作为奇数的奇数数。这是奇数数的一个定义啊,然后最后还有一个value,这个value表示这个节点当中最终要存储的值,这是什么意思呢?
26:06
啊,这就是说大家前面可以看到,我要是寻值,比方说前面这个吧,我这里I这个这个节点我不光是要往下边去分叉,我这个节点直接就对应一个值了。那。那大家想我还需要去单独再分叉一个出来,去去指向另外一个存储值的一个节点吗?其实不需要,直接我存在这个里面就可以了,对吧?表示找到这里为止,这个I找到了它的值就是11,所以我在后面再跟一个value这样的一个一个存储空间直接存它对应寻址寻到这里为止的那个值,这是这个定义啊。它这个怎么样来来呃,用另外一种方式去理解呢,大家可以理解成I0到in呢,这是一个槽位,就相当于大家可以理解成它的这个节点里面分成了很多个插槽。
27:04
每一个插槽里边。都可以。放一个指针,这个指针会引到它对应的检索的字典序的那棵树里面去。所以那么大家就会想到了啊,就这里就是说存这个槽位里面存储的或者是闹,或者是空的,或者是指向另一个节点的指针。那么我们在访问的时候,其实就是利用它节点里边插槽的这个索引值。来指代我们key的路径。啊,这个大家,呃,可能会有点难理解是吧,好,那么我们接下来看一个具体的例子吧,大家看一下啊。假如说我们现在有一个建制队,就是这个key叫做dog,然后这个value叫做puppy啊puppy是小狗的意思对吧,一个dog,它它的下面的这个值是帕Y,那这样一个建制队,我们先不说以太坊具体存储大家知道,具体存储是前面讲了,它是要转成哈希对吧?K转成哈希,然后这个值是要转成这个rfp的这个编码方式,这个我们先不说啊,我们就直接直观的说他这个东西怎么存就存这个东西到。
28:23
那么我们这里首先我们要把do先做一个编码,对吧,用英文字符的这个编码的话,这个就呃52个,这个就太太繁琐,就是太麻烦了,我们可能画也画不出来,以太坊里边应用的是什么样的一个编码字符集呢?是用hes字符集,所以我们这里也就用16进制的汉字符作为我们我们的这个字母表,所以我们字母表里面其实就是。零到。F对吧,就是16个字符,所以这就是16定制字符,就作为我们的字母表里边的字符,那我们怎么样去做这样的一个对应关系去做存储呢?首先我们把dog它先得转换成这个汉字符,对吧?要不然我们没法存,所以先把它转换成S购嘛,那就可以得到我们知道S码的话,其实就是可以表示成二进制,也可以表示成16进制,对吧?那就可以得到四集里面的表示了,比如说DOGDOG这三个字符,它的表示是什么呢?646F67。
29:29
这就是DOG3个字符的表达,那这就是我们要存储的键,我们的K对吧?啊,现在就找到这个K。接下来我们按照它的字母序,也就是六到四到六到六,F到F到六,再到七。这就是我们在。这样一个奇数数或者字典数里边的访问路径。他是拿key当成访问路径的。然后呢,我们的做法是什么呢?是从树的根节点出发。首先读。
30:05
索引值为六的那个插槽,插槽。里边存储的值。然后以它为鉴,访问到对应的子节点里面去。所以这是相当于是什么呢?就是拿六作为一个索引。然后作为我们的路径去访问下一个节点。有点绕是吧?啊,我们先把这个先先过一遍,先说完啊,一会儿给大家看图,然后呢,它下一个不是四吗?我们再找到它的,刚才我们访问到子节点了,子节点再找它索引值为四的插槽。再找到里面对应的值。这是我们要访问的下一个节点。然后我们再跳到下一个节点去,然后到下一个节点再找他的插槽六。然后再找下一个节点。再找下一个节点就是插插槽F对吧,一层一层。一直涨下去。
31:00
直到我们完成了这个路径,找到最后一个节点,它的第七个插槽里边存储的那个值,那个位置就是我们能够找到。我们想要访问的value的那个地方,然后根据那个值就能找到我们的puy这个值啊,这个光看这个步骤就太绕了,我们看看图吧,这个图其实画出来就是这样啊,大家可以看这里边的每一每一排,大家看起来像一个表格一样,其实它就是我们的一个节点。它的节点上面这一排是什么呢?是给的我们给的索引值,或者说这就是我们给他的一个标志,对吧?那它具体存什么呢?是存在下面这这一行里边。我们可以看到根节点出来。他第一步。去访问,我们想要去访问do这个K的时候,怎么访问,先把do转码之后转成646F67,然后我们直接就找六,我们就到root的第六个插槽位去找。
32:08
这个插槽位存的是什么呢?存的是下一个节点的哈希。或者说存的是下一个节点的指针。我们可以理解成存的是指针,那么我们拿到这个指针是不是就直接可以访问到下一个节点了,好,那么我们直接就跳到了下一个节点,那这个节点就代表什么呢?代表六这个K。对应的那个节点对吧。所以这里如果有值的话,它其实就是六对应的值。但是我们这里没值没值,我们继续查第二个路径,我们的K第二个路径是四,那么我们继续就找第二个节点里边的四这个插槽,然后同样它也存着一个地址,或者说存着一个指针,它我们根据这里存着的东西就可以跳转到下一层节点。
33:02
然后呢,这个节点对应存着的东西就是六四对吧,六四这个K对应的东西,但是我们要的还不是,那这个六四代表的是D嘛,我们要的是dog,那我们继续往下一层一层去找,所以大家可以看到继续找这里的第六个。插槽,然后这里是DF的插槽对吧,然后这里是第六个,这里是第七个,最后我们遍历完这个路径的时候就会发现。诶,下面一层,当然我这里是直接就给它写出来,这是一个叶子节点了,就是它不再去分叉了,对吧,当然也有可能它还是一个可以分叉的一个节点,就是一个可以分支的节点,那那个时候的话,这个帕就会写在这个value里边对不对。所以这里我们是没有分叉,那直接它就一个,那那这里就是我们要查找的这个值它。所以大家理解一下,就是所谓的这个字点数和奇数数,它再去寻值。
34:05
找一个存储一个键值对的时候,到底是用什么样的方式去存的,它是这样的方式。
我来说两句