关于栈、数组、链表、队列的形象解释
我是一个栈,先来跟你介绍一下我的家族,我的家族是一个很古老的家族,家族成员很多,外界称呼我们这个家族为数据结构。我们是计算机世界中存储和组织数据的。数据结构家族在计算机世界中是至关重要的,因为我们家族功能的强大,现代编程语言及其API中都有我们家族成员的身影。
我的家族是一个庞大的家族。家族中也有几大分支,比如说树、图、堆、散列表等。各个分支都有不同的能力,所以很多人选择适当的数据结构是一项很重要的工作。我们家族和算法家族是世交,基本上所有重要场合两家都会一起出现。
我叫栈,我的爸爸叫数组,我的妈妈叫链表,我的双胞胎弟弟叫队列。我们这个家庭是整个数据结构家族中比较重要的家庭。
和你说过了,我们数据结构家族是计算机世界中储存和组织数据的。我的家族之所以这么强大,就是因为我们要应付各种需求,提供不同的数据存储方式。我的四个家庭成员分别可以解决不同的数据存取需求。
数组
说起我的爸爸——数组,他是数据结构家族的族长,人们都说他是数据结构大家族的根基。很多编程语言都内置数组。
数组爸爸是个很富有的人,他有很多土地。每当有人找他来存储数据的时候,他都会预先划分出一块连续的土地(连续的内存),然后把别人交给他的数据按顺序存储在这些连续的土地中,当别人来取这些数据的时候,需要提供给数组要取哪块土地中的数据(数组的位置索引),然后数组就可以直接去那块土地中把数据取出来,交给需要读取这个数据的人。并不是所有数据数组都能帮忙存储的,父亲只会帮别人存储相同类型的数据。
数组数据结构是由相同类型的元素(element)的集合所组成的数据结构,分配一块连续的内存来存储。利用元素的索引(index)可以计算出该元素对应的存储地址。
我的家族的所有人都支持几个基本的操作:插入、删除、读取。
因为数组爸爸在存储数据的时候,是按照顺序保存的,他保存数据的土地是一块一块相连的。那么,他的特点就是寻址读取数据比较容易,但是插入和删除比较困难。这个其实比较好理解。读取容易的原因是只要你告诉数组你要从哪块土地读取数据,他就会直接去那块土地中把数据取出来给你。插入和删除比较麻烦,主要是因为这些存储数据的空间都是连着的,比如编号为0-1-2-3-4这五块土地中都保存了数据,但是现在你要往1中插入一块数据,那就意味着从1开始,后面的所有土地中的数据都要往后移一个位置。这是很大的工作量啊。
链表
人们都说,男女搭配,干活不累。由于数组爸爸有寻址容易,插入和删除困难的问题,他在找老婆的时候特意找了一个和自己互补的姑娘——链表。链表妈妈的特点正好是寻址困难,插入和删除容易。
在帮助别人存储数据这件事上,链表的方式和数组有很大不同。数组是提前划分了一大片连续的土地,用来存储数据。但是链表不是这么做的,因为链表妈妈家里并没有数组爸爸家里那么富有。他的数据存储并不是连续的,能这么做的原因是妈妈存储数据的土地中有两块区域,一块用来保存数据,一块用来记录下一个数据保存在哪块土地中(指针)。这样,别人找他存储数据的时候,她就要根据指示先找到下一块空余的土地,然后把数据保存在里面。链表这样的数据存储方式可以把一些碎片空间利用起来。
链表是一种线性表,但是并不会按线性的顺序存储数据,而是在每一个节点里保存着下一个节点的指针。
通过上面的这种保存数据的方式,链表在插入和删除数据的时候比较容易,比如编号为0-1-2-3-4这五块土地中都保存了数据,但是现在你要往1中插入一块数据,那么只需要依次更改0号土地和1号土地中记录下一块土地地址的值就行了。对于其他的数据存储没有任何影响。但是,如果你想从数据中取出一块数据那可就麻烦了,因为这意味着链表妈妈要帮你从第一块土地开始挨个帮你找。一直找到你要的数据为止。
我和我的胞弟
栈,也就是我,一个英俊潇洒的数据结构。我和队列是一堆孪生兄弟。我们两个都可以用数组和链表来实现。虽然是双胞胎,但是我们两个都是有性格的,我们要求别人存储数据和取出数据的顺序要按照我们的规矩来。
我的原则是:先进后出(栈)
弟弟的原则是:先进先出(队列)
我给你举个例子你就明白了,我和弟弟每个人都有一个管子,用来帮你们保存数据,当然这个管子可能是用数组爸爸是实现的也可能是链表妈妈实现的。我们握住管子的两头,我的这个管子只能通过管子左面的口子放入东西,也只能从左面的口子取出东西。右面的口子是不开的。而弟弟队列呢,他的管子的左面的口子放东西,管子的右面的口子取东西。
爸爸妈妈是如何生出我和弟弟的
上面说过了,栈和队列都是可以通过数组或者链表实现的。当然了,父母创造孩子,天经地义嘛。那么,先来看看我是如何实现的。作为一种数据结构,我接口有isEmpty()、size()、push()、pop()、peek()以及迭代。
先来看看如何通过数组实现栈:
再来看看如何使用链表实现栈:
同样作为数据结构的弟弟,也有些接口需要实现:isEmpty()、size()、enqueue()、dequeue()、peek()以及迭代。队列和栈不同的是,入列和出列是在两个地方,所以需要维护两个变量来表示队头和队尾。
使用数组实现队列:
public class Queue
使用链表实现队列:
public class Queue
我是一个栈,我的双胞胎弟弟叫队列。我的爸爸是数组,我的妈妈是链表。 你们可以使用数组和链表来实现栈和队列。
好了,今天关于我和我的家族的故事就先给你介绍到这里了。偷偷告诉你一个秘密,其实我和弟弟之间是可以互相转换的。也就是说可以使用栈来实现队列,同样也可以使用队列来实现栈。关于这个小秘密,我下次再给你介绍哦。
感谢大家阅读由Java教程分享的“关于栈、数组、链表、队列的形象解释”希望对大家有所帮助,更多精彩内容请关注Java培训官网
免责声明:本文由小编转载自网络,旨在分享提供阅读,版权归原作者所有,如有侵权请联系我们进行删除
【免责声明】本文部分系转载,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责,如涉及作品内容、版权和其它问题,请在30日内与我们联系,我们会予以重改或删除相关文章,以保证您的权益!
Java开发高端课程免费试学
大咖讲师+项目实战全面提升你的职场竞争力
- 海量实战教程
- 1V1答疑解惑
- 行业动态分析
- 大神学习路径图
相关推荐
更多2015-10-15
2015-10-15
达内就业喜报
更多>Java开班时间
-
北京 丨 11月27日
火速抢座 -
上海 丨 11月27日
火速抢座 -
广州 丨 11月27日
火速抢座 -
兰州 丨 11月27日
火速抢座 -
杭州 丨 11月27日
火速抢座 -
南京 丨 11月27日
火速抢座 -
沈阳 丨 11月27日
火速抢座 -
大连 丨 11月27日
火速抢座 -
长春 丨 11月27日
火速抢座 -
哈尔滨 丨 11月27日
火速抢座 -
济南 丨 11月27日
火速抢座 -
青岛 丨 11月27日
火速抢座 -
烟台 丨 11月27日
火速抢座 -
西安 丨 11月27日
火速抢座 -
天津 丨 11月27日
火速抢座 -
石家庄 丨 11月27日
火速抢座 -
保定 丨 11月27日
火速抢座 -
郑州 丨 11月27日
火速抢座 -
合肥 丨 11月27日
火速抢座 -
太原 丨 11月27日
火速抢座 -
苏州 丨 11月27日
火速抢座 -
武汉 丨 11月27日
火速抢座 -
成都 丨 11月27日
火速抢座 -
重庆 丨 11月27日
火速抢座 -
厦门 丨 11月27日
火速抢座 -
福州 丨 11月27日
火速抢座 -
珠海 丨 11月27日
火速抢座 -
南宁 丨 11月27日
火速抢座 -
东莞 丨 11月27日
火速抢座 -
贵阳 丨 11月27日
火速抢座 -
昆明 丨 11月27日
火速抢座 -
洛阳 丨 11月27日
火速抢座 -
临沂 丨 11月27日
火速抢座 -
潍坊 丨 11月27日
火速抢座 -
运城 丨 11月27日
火速抢座 -
呼和浩特丨11月27日
火速抢座 -
长沙 丨 11月27日
火速抢座 -
南昌 丨 11月27日
火速抢座 -
宁波 丨 11月27日
火速抢座 -
深圳 丨 11月27日
火速抢座 -
大庆 丨 11月27日
火速抢座