浅谈顺序存储结构

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了浅谈顺序存储结构相关的知识,希望对你有一定的参考价值。

存储结构划分

存储结构是什么?即在内存区域用怎样的存储方式,怎样的结构存储数据,把一百双鞋子比喻成数据元素,摆放鞋子的地方就是内存区域,而鞋子可以有不同的摆法,怎样摆才能让人快速找到?

怎样摆才能容易拿(取)放(寸)。在内存中,数据的通过不同的“摆法”,是为了能够占用更少的内存单元或者更快存取。所以就有了 顺序存储结构 和 链式存储结构。

顺序存储结构:

在内存中,分配出一块区域,将数据元素连续存储其中,按照一定的顺序,如:

int arrary []={1,2,3,4,5,6,}
  我定义了一个数组,就是在内存单元中开辟了一个存储区域,用于摆放上文提到的“鞋子”。一眼望去,这个数组有6个存储了元素的存储单元,对,他们紧挨着,就像邻居一样
从存储结构上讲,这就是顺序存储。arrary[0]是 1,它的隔壁不是老王,是 arrary[1],即 2;

现在有几个问题:

1.我怎么在内存区域中找到这个数组 (编程语言的知识)

2.我的数据元素为什么要这样存储,有什么好处?

3.它的缺点是什么?

答:

1.众所周知,我们在访问数组的时候,需要使用数组名,

比如我访问数组的第一个元素:arrary[0]

第二个元素:arrary[1];

好吧,这个很浅显,我们在定义数组的时候,数组名就是 这个存储区域的地址,系统通过数组名(地址)找到了这个 内存中这个存储了这些元素的区域,

从我访问第一个元素和第二个元素可以看出,在线性存储结构中,我想访问元素单元是很容易的,对,这就是线性存储结构的优势所在

 

2. 上文其实以及说到,我访问其中的元素很容易,因为他们给了 固定连续的位置,如图

技术分享

(图1 来源:百度图片)

图一,看起来就像大鞋柜,每一层都是固定的位置,我第一层就放 我经常穿的鞋子,第二层我就放 拖鞋......

每次我要拿的时候,我只要根据位置就可以了。

在上文的数组定义中,int 决定了这个大柜子里面装的是 int 型数据,系统会根据数据类型量身打造,分配可以存放该数据的内存空间,不会太大也不会太小。

你家的鞋柜会做得桌子也能放进去吗?显然没有,那多浪费空间,在内存存储中,第一我们要快速存取,第二我们要尽量节省内存空间

总结:顺序存储结构:读取快,节省内存空间.

 

3.有利必有弊,在做这个柜子的时候,我设计为6层,但后来我买了10双鞋子,无处摆放了吧?

线性存储结构也是如此,当我定义了,它就只能按照当初定义时的大小,多出的东西没办法塞进去,就容易溢出了。

回过头来,2中我们谈到它量身定做的属性,说它因此而节省内存空间,其实.....在实际应用中,我定义一个数组,为了避免溢出情况,可能会尽量使其分配足够的内存空间

int a[100]={10,20,30,40,};

但我实际就用了 4个存储单元,其它的就目前而言,空间浪费了

所以,它的一大缺点就是:有空间限制,当空间不够时,容易溢出,当元素个数远少于之前预分配的,造成空间浪费

调试一下看看:

先定义:

技术分享

(图 2 )

在观察:

技术分享

(图3)

除了4个内存单元有 用到的 其它是不是默认为0 还没有用到,但它确确实实占用你的内存呀!

还有,我现在不止4个数据了 我要存1000个,存不进了吧,666

还有:从图3可以看到

a[0]=10; a[1]=20;a[2]=30;a[3]=40;

 

那么,我现在要在其中插入一个数,比如我要在a[1]这个位置插入15

插入后就是:

a[0]=10; a[1]=15;a[2]=20;a[3]=30;a[4]=40;

注意是 插入 不是把a[1]设置为15,所以原先数组用了 4个存储单元来存放元素,插入一个,现在要用到 5个了

怎么做?:

先判断我这个数组是不是有足够的存储单元?我定义了100个,显然太够了

然后我插入的位置是否合理?我插入在a[1]这个位置,在数组中 显然逻辑位置 pos=2;它不是奇奇怪怪的a[-1]或者a[101],显然合理

那么就来插吧,首先我需要把原数组中,a[1]到a[4]中的元素都往后挪一个位置,这样才能空出一个单元来安放我要插入的元素:

如:

//前面省略若干啰里啰唆的代码
int item=15;//要插入的值为15 int pos=1;//要插入的物理位置为 a[1]; for(int i=4;i>=pos;i--) { a[i+1]=a[i]; } a[pos]=item; //终于把15插进去了

上面那个for循环干嘛?

看看调试就知道了:

上车

技术分享

(图4 我把数组改为 6 个单元了   为了方便)

(0)还没执行循环时:

技术分享

(1)循环走一圈:

技术分享

注意:a[3]=40,a[4]=40? 显然,该元素往后挪了一个位置

那两个相同怎么办?别急

(2)循环再走一圈:

技术分享

现在是a[2]往后挪了一个位置 覆盖了原来的a[3]的值;

(....)经过循环之后:

技术分享

如愿以偿。说白了,for循环里面的作用可以这样比喻:

一群人在排队,他是线性结构的,所以从第一个人到最后那个大兄弟的队伍是一条直线,

我想插队,在第2个位置插入,原先的老二到最后那个大兄弟是不是就得往后挪一个位置,

而上文的操作为了证明,我插入一个元素的时候,是先让最后一个元素往后挪,然后倒数第二个元素也往后挪占在刚刚第一个挪的位置,

遍历循环下来,中间就空出一个位置,以便让我插入!

说了那么多,如果你还不懂,把文中的代码好好咀嚼一下 0_0

通过这个例子,可以得出:我就插入一个数,至于这么麻烦吗?

对,就是这么麻烦!

所以这也是顺序存储结构的另一大缺点,插入麻烦!

数据操作,无非增删查改。

 

 

 

 

 

本文浅显鄙陋,亦恐有不足,望指出,以作学习交流之用。适合编程入门者阅

by TL on 2017/10/4




以上是关于浅谈顺序存储结构的主要内容,如果未能解决你的问题,请参考以下文章

浅谈PHP数据结构之单链表

浅谈数据结构之线性表链式存储

浅谈全方位查找

浅谈数据结构之图的邻接表深度和广度优先遍历

浅谈数据结构之链队列

浅谈java类中成员的初始化顺序