常见的数据结构,有以下几种:
1、数组(Array)
2、栈(Stack)
3、链表(Linked List)
4、队列(Queue)
5、树(Tree)
6、图(Graph)
7、堆(Heap)
那么我们分别对他们进行一个整理总结。
一、数组
数组就是可以在内存中存储多个元素的结构,其中的元素类型必须相同,而且在内存中是连续的,数组的元素是通过数组的下标访问,不是从1开始,而是从0开始。
栗子:int [ ] data = new int[50];
data[0] = 1;
它表示初始化了一个整型数组,数组名为data,数组长度是50,每个元素类型都是int型,在内存中的地址是连续的。并且赋值第一个元素为1。
因为数组在存储数据时是按顺序存储的,存储数据的内存也是连续的,所以他的特点就是读取数据比较容易,插入和删除比较困难。简单解释一下为什么,在读取数据时,只需要告诉数组要从哪个位置(索引)取数据就可以了,数组会直接把你想要的位置的数据取出来给你。插入和删除比较困难是因为这些存储数据的内存是连续的,要插入和删除就需要变更整个数组中的数据的位置。
优点:
1、按照索引查询速度快,遍历数组方便。
缺点:
1、数组只能存储一种类型的元素。
2、数组的大小定义完之后固定,无法扩容。
3、添加和删除的操作慢,因为数组内存地址是连续的,需要移动其他元素
适用于频繁查询,对存储空间要求不大,而且很少删除和增加元素的情况。
二、栈
栈只允许在栈顶进行操作,栈底不允许操作。栈的特点是:先进后出,或者是后进先出。在栈顶放入元素的操作是入栈,取出元素的操作是出栈。
栗子:栈的结构很像集装箱,越先放进去的东西,越晚才能拿出来,最后放进去的东西,最先拿出来。
三、链表
链表是存储单元上不连续的的存储结构,数据元素的逻辑顺序是通过链表的指针地址来实现的。每个元素包含两个节点。一个节点是存储元素的数据域,另一个节点是指向下一个节点的指针域。根据指针的指向,可以行成不同的结构,例如:单链表,双向链表和循环链表。
链表是由一系列的节点组成,这些节点不必在内存中连续,当添加和删除元素的时候,只需要改变相关节点的指针指向即可,效率很高。
单链表:最后一个结点的指针域设置为空(NULL),作为链表的结束标志,表示它没有后继结点。
双向链表:每个节点的指针域都有两个指针,分别指向它的后继和前驱,所以,从从任意节点开始,都能方便的访问它的前驱节点和后继节点。
循环链表:从单链表可知,最后一个节点的指针域指向NULL,当我们将尾指针指向头结点,那么就形成了一个循环链表。
优点:1、不需要初始化容量,可以任意增减元素。
2、添加或者删除元素时,只需要改变前后两个元素的指针指向即可,删除和添加元素会很快。
缺点:1、查找元素需要遍历链表来实现,很耗时。
2、链表存在大量的指针域,占用空间大。
四、队列
队列类似于栈,不同的是队列是在一端增加元素,在另一端取出元素,特点是:先入先出,后入后出。放入元素的操作被称为入队,取出元素的操作被称为出队。
栗子:队列的结构像是一根水管,从一个口入,另一个口出。
五、树
上面的链表、队列、栈,都是线性表,因为其中每个数据元素只有一个前驱和一个后继,是一对
一的关系。假如是一对多的关系呢?这种数据结构就是树。
树是由n个(n>=0,n=0是,是一棵空树)有限节点构成的,是一个具有层次关系的集合。它看起来像是一棵倒挂的树,也就是说根朝上,而叶子朝下的。
特点:1、每个节点具有零个或者多个子节点。
2、没有父节点的节点称为根节点。
3、每一个非根节点有且只有一个父节点。
4、除了根节点以外,每个子节点可分为多个不相交的子树。
二叉树是树的一种,每个节点最多可具有两个子树,即结点的度最大为2(结点度:结点拥有的子树数)。