数据结构

数据结构

决定数据存储于内存时数据顺序和位置关系

链表

蓝黄红三个字符串被存储在链表中,每个数据都有存储一个指向下一个数据内存地址的“指针”

因为有指针索引,链表结构的数据可以分散在存储空间中,无需连续。

也因存储是分散的,如果要访问数据,只能从第一个数开始向下逐个访问。

比如要找到红就要蓝→黄→红

链表指针

得益于有指针指向,若要在链表中加入数据,只需要改变插入位置前后的指针就可以

比如在蓝黄间加入绿,只要把绿指针指向黄,蓝指针指向绿

 链表插入

要删除时,比如删除黄只要把绿指针由黄改为指向红,黄不变等日后被覆盖即可

查找时间复杂度O(n)

添加时间复杂度O(1)

--------------------------------------------------------------------------------

数组

在数组中数据按顺序存储在内存的连续空间内,每个数据的内存地址可以通过数组下标算出,可以随机访问目的数据

 随机访问

相比可以方便的随机访问,要在数组中添加数据就比较复杂了

比如要在数组的蓝黄之间添加绿

首先在数组末尾添加所要增加的存储空间

再把已有的数据一个个往后移

最后在空出来的位置上写入

 数组插入

同样删除绿,先将绿移除,再将后面的数据一个个往前移,最后删除多余的空间

查找时间复杂度O(1)

添加时间复杂度O(n)

--------------------------------------------------------------------------------

在栈这种结构中,我们只能访问最新添加的数据,就像一堆东西层层叠放,只能从最上面拿取。

栈形象

往栈里添加数据的操作,入栈push;从栈中取出数据的操作,出栈pop。

这种就叫后进先出的结构,Last In First Out (LIFO)

在栈中,添加和删除数据的操作只能在一端进行,访问数据也只能访问到顶端的数据。 

 栈出入

--------------------------------------------------------------------------------

队列

队列顾名思义,就像是排成一 队的人。在队列中,处理总是从第一名开始往后进行,而新来的人只能排在队尾

 队列形象

往队列里添加数据的操作,入队;从队列中取出数据的操作,出队

这种就叫先进先出的结构,First In First Out (FIFO)

 队列出入

在栈中,数据的添加和删除都在同一端进行,而在队列中则分别是在两端进行的。

队列也不能直接访问位于中间的数据,必须通过出队操作将目标数据变成首位后才能访问

--------------------------------------------------------------------------------

哈希表

哈希表存储由键值组成,key、value。比如在这里把姓名为键,把性别为值。

哈希表

 如果这些键值对存储在数组中,为了检索到Ally的性别,在数组中只能重头开始查询。

线性查找

数据量越多,这种线性查找所耗费的时间就越长。所以说数据的查询较为耗时,不是大量存储
在哈希表中,

首先准备好数组,用哈希函数计算每个数据的键,得到字符串的哈希值,

再将得到的哈希值除以数组的长度,求的余数即mod运算,

最后将数据存放相应的数组位置中

若存储位置重复,则可以使用链表在已有的数据后面存储

哈希录入

 查询哈希表中的数据时为 了找到它的存储位置,先要算出键的哈希值,再对其进行mod运算,最终得到的结果。若所对应的还不是目标,则在其所在的链表中继续线性查找。

 

 哈希查找

--------------------------------------------------------------------------------

堆是一种图的树形结构,被用于实现“优先队列”(priority queues)

优先队列是一种数据结构,可以自由添加数据,但取出数据时要从最小值开始按顺序取出。

 堆形象

在堆的树形结构中,各个顶点被称为“结点”(node),数据就存储在这些结点中。

结点内的数字就是存储的数据

堆中的每个结点最多有两个子结点

树的形状取决于数据的个数

结点的排列顺序为从上到下,同一行里则为从左到右。

在堆中存储数据时必须遵守:子结点必定大于父结点,因此,最小值被存储在顶端的根结点中。

往堆中添加数据时,为了遵守这条规则,一般会把新数据放在最下面一行靠左的位置。当最下面一

行里没有多余空间时,就再往下另起一行, 把数据加在这一行的最左端。如果父结点大于子结点,则不符合规则,因此需要交换父子结点的位置。

堆插入 

从堆中取出数据时,取出的是最上面的数据。这样,堆中就能始终保持最上面的数据最小。

当最上面的数据被取出,堆的结构要重新调整。

先将最后的数据移动到最顶端

如果子结点的数字小于父结点,则将父结点和左右两个结点中较小的一个进行交换。重复操作直到数据都符合规则,不再需要交换为止。

取出最小值的时间复杂度 O(1)

重构树的时间复杂度 O(logn)

添加数据需要的运行时间与树的高度成正比,也是 O(logn)

堆导出

--------------------------------------------------------------------------------

二叉查找树

二叉查找树采用了图的树形结构,数据存储于二叉查找树的各个结点中

二叉查找树有两个性质。

第一个是每个结点的 值均大于其左子树上任意一个结点的值。

比如结点9大于其左子树上的3和8。同样,结点15也大于其左子树上任意一个结点的值。

第二个是每个结点的值均小于其右子树上任意 一个结点的值。比如结点 15 小于其右子树上的 23、17和28。

所以二叉查找树的最小结点要从顶端开始,往其左下的末端寻找。

反过来,二叉查找树的最大结点要从顶端开始,往其右下的末端寻找。

若要往二叉查找树中添加数

首先,从二叉查找树的顶端结点开始寻找添加数字的位置。将想要添加的1与该结点中的值进行比较,小于它则往左移,大于它则往右移。

如果需要删除的结点没有子结点,直接删掉该结点即可

如果需要删除的结点只有一个子结点,那么先删掉目标结点,然后把子结点移到被删除结点的位置上即可。

如果需要删除的结点有两个子结点,那么先删掉目标结点,然后在被删除结点的左子树中寻找最大结 点,最后将最大结点移到被删除结点的位置上。

在二叉查找树中查找结点,从二叉查找树的顶端结点开始往下查找,小于该结点的值则往左移,大于则往右移。

--------------------------------------------------------------------------------

原文地址:https://www.cnblogs.com/hereisdavid/p/13553227.html