数据结构
数据存储于内存时,决定了数据顺序和位置关系的便是数据结构。根据使用数据的目的选择合适的数据结构,可以提高内存的利用率。
链表
链表是数据结构之一,其中的数据呈线性排列。链表在内存中无需存储在连续空间内,数据链上的每个数据元素都有一个指针,指向下一个数据的内存地址。因为数据都是分散存储的,所以如果想要访问数据,只能从第1个数据开始,顺着指针的指向一一向下访问(这便是顺序访问)。如果想要添加或删除数据,只需要改变添加位置前后的指针指向就可以,非常简单。
时间复杂度:
假设链表中的数据量是n,访问数据时,需要从链表头部开始查起,如果目标数据在链表最后的话,需要的时间就是O(n)。而添加和删除数据只需要更改两个指针的指向,所以耗费的时间与n无关。如果已经到了添加数据的位置,那么添加操作只需要花费O(1)的时间。
除常规链表外,还有几种变种的扩展链表。
循环链表:在链表尾部增加指针指向链表头部,将链表形成环形,这便是“循环链表”也叫“环形链表”。通常在保存数量固定的最新数据时会使用这种链表。
双向链表:为链表上的每个数据设置两个指针,且让他们分别指向前后数据的内存地址,这就是“双向链表”。使用这种链表不仅可以从前往后,还可以从后往前遍历数据,十分方便。同时双向链表也存在两个缺点,一是指针数的增加会导致存储空间需要增加;二是添加和删除数据时需要改变更多指针的方向。
数组
数组也是数据呈线性排列的一种数据结构。数据按顺序存储在内存的连续空间内,也因此每个数据的内存地址都可以通过数组下标计算得出,所以可以借此直接查找目标数据即“随机查找”。同样,也是因为连续的内存空间存储,在添加和删除操作时,需改调整各个数据的存储位置,操作效率较低。
时间复杂度:
假设数组中有n个数据,由于访问数据时使用的是随机访问,所以需要的运行时间仅为恒定的O(1)。但另一方面,向数组中添加数据时,必须把目标位置后面的数据一个个移开,如果在数据头部添加数据,就需要O(n)的时间。删除操作同理。
栈
栈也是一种数据呈线性排列的数据结构,不过在这种数据结构中,我们只能访问最新添加的数据。栈就像是一摞书,拿到新书时我们会把它放在书堆的最上面,取书时也只能从最上面的新书开始取。像栈这种最后添加的数据最先被取出来,即“后进先出”的数据结构被称为Last In First Out,简称LIFO.
入栈:往栈中添加数据的操作叫作“入栈”。
出栈:从栈中取出数据的操作叫作“出栈”。
队列
队列中的数据也呈线性排列。虽然与栈有些相似,但队列中添加和删除数据的操作分别是在两端进行的。往队列中添加数据时,新数据将添加在老数据的上面,从队列中取出(删除)数据时,是从最下面,也就是最早入队的数据开始的。像队列这种最先进去的数据最先被取出,即“先进先出”的结构,被称为First In First Out,简称FIFO。
入队:往队列中添加数据的操作叫作“入队”。
出队:从队列中删除数据的操作叫作“出队”。
队列和栈可以操作数据的位置都是有固定限制的