0204:数据结构-比较
本文依照学习难度,分成入门、进阶两个部分。
入门部分以直观、易于理解为主;进阶部分重点在于概念、推导等。
目录
入门
优缺点
使用数组存储数据时,当插入新数据,通常需要将数据移动到足够的连续空间里,或者在最初预留足够的空间
这样的存储方式麻烦且浪费
但是链表可以分开来存储
使用链表查询数据时,当需要读取最后一个元素时,不能直接读取,需要先访问第一个元素,由第一个元素获取第二个元素的位置,直至最后一个元素。
而数组的元素是连在一起的,可以想象成位置也是连着的,很容易计算得到第n个元素位置是多少。 因此在随机读取元素时,数组的效率很高。
两者各有各的优点,各有各的缺点。最理想的当然是能组合两者,最大的发挥其中的优点。
链表数组是其中的一种组合方式。
链表数组
此时,存储新数据,如Adit时,首先访问数组的第一个元素,再访问该元素指向的链表,并将Adit添加到这个链表末尾。
现实中,会根据不同的应用场景选择不同的存储方式,再进行组合。比如Facebook实际使用的很可能是十多个数据库,它们基于众多不同的数据结构:散列表,B树等。数组和链表是这些更复杂的数据结构的基石。
模拟链表
前面的链表部分使用指针去链接下一个数(指出右边的数是谁)
链表还有另外一种使用数组来实现的方式,叫做模拟链表
这里面只需用一个数组来存放序列中每个数右边的数是谁就可以。
举个例子:
如上图所示,第一个整数数组data是用来存放序列中具体数字的;另一个整型数组right是用来存放当前序列中每一个元素右边的元素在数组data中未知的e
比如,right[1]的值为2,就表示当前序列中1号元素右边的元素存放在data[2]中。right[9]=0,表示当前序列9号元素的右边每一元素。
那插入操作如何做呢?
现在需要在8前面插入一个6.只需要将6存放在数组data的末尾。接下来将right[3]=10,right[10]=4.
如下图所示:
实现的代码是:
# include <stdio.h>
int main()
{
int data[101],right[101];
int i,n,t,len;
//读入已有的数
scanf("%d",&n);
for(i=1;i<n;i++)
scanf("%d",&data[i]);
len=n
//初始化数组right
for(i=1;i<n;i++)
(
if(i!=n)
right[i]=i+1;
else
right[i]=0;
)
//直接在数组data的末尾增加一个数
len++;
scanf("%d",$data[len]);
..
进阶
[1] 算法图解 Aditya Bhargava (作者) 袁国忠 (译者)
