数据结构:数组、链表、堆栈、队列
2016-10-20 12:03
513 查看
数据结构:是指相互之间存在一种或多种特定关系的数据元素的集合。听起来是不是很抽象,简单理解:数据结构就是描述对象间逻辑关系的学科。比如:队列就是一种先进先出的逻辑结构,栈是一种先进后出的逻辑结构,家谱是一种树形的逻辑结构!(初学数据结构的时候很不理解为什么有“栈”这个东西;队列很容易理解---无论购物就餐都需要排队;栈可以认为就是个栈道---只允许一个人通过的小道,而且只能从一端进入,然后再从这端返回,比如你推了个箱子进去啦,第二个人也推个箱子进去,此时只能等后进来的这个人拉着箱子出去后,你才能退出。)
数据存储结构:它是计算机的一个概念,简单讲,就是描述数据在计算机中存储方式的学科;常用的数据存储方式就两种:顺序存储,非顺序存储!顺序存储就是把数据存储在一块连续的存储介质(比如硬盘或内存)上----举个例子:从内存中拿出第100个字节到1000个字节间的连续位置,存储数据;数组就是典型的顺序存储!非顺序存储就是各个数据不一定存在一个连续的位置上,只要每个数据知道它前面的数据和后面的数据,就能把所有数据连续起来啦;链表就是典型的非顺序存储啦!
数组、链表、堆栈和队列是最基本的数据结构,任何程序都会涉及到其中的一种或多种。
数组是最最基本的数据结构,很多语言都内置支持数组。数组是使用一块连续的内存空间保存数据,保存的数据的个数在分配内存的时候就是确定的:
图 1.1 包含 n 个数据的数组
访问数组中第 n 个数据的时间花费是 O(1) 但是要在数组中查找一个指定的数据则是 O(N)。当向数组中插入或者删除数据的时候,最好的情况是在数组的末尾进行操作,时间复杂度是O(1) ,但是最坏情况是插入或者删除第一个数据,时间复杂度是 O(N) 。在数组的任意位置插入或者删除数据的时候,后面的数据全部需要移动,移动的数据还是和数据个数有关所以总体的时间复杂度仍然是 O(N) 。
图 1.2 向数组中插入数据
链表是在非连续的内存单元中保存数据,并且通过指针将各个内存单元链接在一起,最有一个节点的指针指向 NULL 。链表不需要提前分配固定大小存储空间,当需要存储数据的时候分配一块内存并将这块内存插入链表中。
在链表中查找第 n 个数据以及查找指定的数据的时间复杂度是 O(N) ,但是插入和删除数据的时间复杂度是 O(1) ,因为只需要调整指针就可以:
图 2.1 链表
图 2.2 向链表中插入一个数据
图 2.3 从链表中删除一个数据
向上面这样的链表结构在插入和删除的时候编程会比较困难,因为需要记住当前节点的前一个节点,这样才能完成插入和删除。为了简便通常使用带有头节点的链表:
图 2.4 带有头节点的单链表
上面的链表是单链表,此外还有双链表,就是节点中包含指向下一个节点的指针和指向上一个节点的指针:
图 2.5 双向链表
不带有头节点的双向链表在插入和删除数据的时候也不会出现单链表那样的问题。此外还有一种链表是循环链表,它是将双向链表的头尾相接:
图 2.6 双向循环链表
向循环双向链表和循环链表中插入或者从中删除数据只是多移动几个指针。
堆栈实现了一种后进先出的语义 (LIFO) 。可以使用数组或者是链表来实现它:
图 3.1 堆栈
对于堆栈中的数据的所有操作都是在栈的顶部完成的,只可以查看栈顶部的数据,只能够向栈的顶部压入数据,也只能从栈的顶部弹出数据。
队列实现了先入先出的语义 (FIFO) 。队列也可以使用数组和链表来实现:
图 4.1 队列
队列只允许在队尾添加数据,在队头删除数据。但是可以查看队头和队尾的数据。还有一种是双端队列,在两端都可以插入和删除:
图 4.2 双端队列
缺点:输入,删除的速度慢
类库中已定义的列表类:System.Collections.ArrayList 非泛型
System.Collections.Generic.List<T>泛型
支持的功能:添加 Add,删除 RemoveRemoveAt RemoveRange,
插入 Insert ,查找 Contains,索引 this[index],统计数量 Count,
清空 Clear
List新增的方法:FindFindAll FindIndex FindLastIndex RemoveAll
扩展方法:Sum Max Min Aveage OrderBy OrderByDescending Any All ……..
支持的操作:增加Add,删除 Remove ,清空 Clear ,检查存在ContainsKeyContainsValue
属性: 个数Count, 键集合Keys,值Values
支持操作:入栈 Push,出栈 Pop,读栈顶 Peek,个数 Count
类库中已定义的栈类System.Collections.Stack System.Collections.Generic.Stack<T>
支持操作:入队Enqueue,出队Dequeue,读队首Peek,个数Count
类库中已定义的队列类System.Collections.Queue System.Collections.Genric.Queue<T>
支持的操作:增加Add,删除 Remove ,清空 Clear ,检查存在ContainsKeyContainsValue
属性: 个数Count, 键集合Keys,值Values
支持的操作加在头AddFirst加在尾 AddLast 插入前 AddBefore 插入后 AddAfter
查找 Find
数据存储结构:它是计算机的一个概念,简单讲,就是描述数据在计算机中存储方式的学科;常用的数据存储方式就两种:顺序存储,非顺序存储!顺序存储就是把数据存储在一块连续的存储介质(比如硬盘或内存)上----举个例子:从内存中拿出第100个字节到1000个字节间的连续位置,存储数据;数组就是典型的顺序存储!非顺序存储就是各个数据不一定存在一个连续的位置上,只要每个数据知道它前面的数据和后面的数据,就能把所有数据连续起来啦;链表就是典型的非顺序存储啦!
数组、链表、堆栈和队列是最基本的数据结构,任何程序都会涉及到其中的一种或多种。
1 数组
数组是最最基本的数据结构,很多语言都内置支持数组。数组是使用一块连续的内存空间保存数据,保存的数据的个数在分配内存的时候就是确定的:图 1.1 包含 n 个数据的数组
访问数组中第 n 个数据的时间花费是 O(1) 但是要在数组中查找一个指定的数据则是 O(N)。当向数组中插入或者删除数据的时候,最好的情况是在数组的末尾进行操作,时间复杂度是O(1) ,但是最坏情况是插入或者删除第一个数据,时间复杂度是 O(N) 。在数组的任意位置插入或者删除数据的时候,后面的数据全部需要移动,移动的数据还是和数据个数有关所以总体的时间复杂度仍然是 O(N) 。
图 1.2 向数组中插入数据
2 链表
链表是在非连续的内存单元中保存数据,并且通过指针将各个内存单元链接在一起,最有一个节点的指针指向 NULL 。链表不需要提前分配固定大小存储空间,当需要存储数据的时候分配一块内存并将这块内存插入链表中。在链表中查找第 n 个数据以及查找指定的数据的时间复杂度是 O(N) ,但是插入和删除数据的时间复杂度是 O(1) ,因为只需要调整指针就可以:
图 2.1 链表
图 2.2 向链表中插入一个数据
图 2.3 从链表中删除一个数据
向上面这样的链表结构在插入和删除的时候编程会比较困难,因为需要记住当前节点的前一个节点,这样才能完成插入和删除。为了简便通常使用带有头节点的链表:
图 2.4 带有头节点的单链表
上面的链表是单链表,此外还有双链表,就是节点中包含指向下一个节点的指针和指向上一个节点的指针:
图 2.5 双向链表
不带有头节点的双向链表在插入和删除数据的时候也不会出现单链表那样的问题。此外还有一种链表是循环链表,它是将双向链表的头尾相接:
图 2.6 双向循环链表
向循环双向链表和循环链表中插入或者从中删除数据只是多移动几个指针。
3 堆栈
堆栈实现了一种后进先出的语义 (LIFO) 。可以使用数组或者是链表来实现它:图 3.1 堆栈
对于堆栈中的数据的所有操作都是在栈的顶部完成的,只可以查看栈顶部的数据,只能够向栈的顶部压入数据,也只能从栈的顶部弹出数据。
4 队列
队列实现了先入先出的语义 (FIFO) 。队列也可以使用数组和链表来实现:图 4.1 队列
队列只允许在队尾添加数据,在队头删除数据。但是可以查看队头和队尾的数据。还有一种是双端队列,在两端都可以插入和删除:
图 4.2 双端队列
列表:List<T> ArrayList
特点:有序,内存空间连续,读取速度快,大小可变,通过位置索引取元素.缺点:输入,删除的速度慢
类库中已定义的列表类:System.Collections.ArrayList 非泛型
System.Collections.Generic.List<T>泛型
支持的功能:添加 Add,删除 RemoveRemoveAt RemoveRange,
插入 Insert ,查找 Contains,索引 this[index],统计数量 Count,
清空 Clear
List新增的方法:FindFindAll FindIndex FindLastIndex RemoveAll
扩展方法:Sum Max Min Aveage OrderBy OrderByDescending Any All ……..
字典: Dictionary<TKey,TValue>,Hashtable
特点:键值对的集合,通过键查找值,查找方便,无序支持的操作:增加Add,删除 Remove ,清空 Clear ,检查存在ContainsKeyContainsValue
属性: 个数Count, 键集合Keys,值Values
栈: Stack<T> ,Stack
特点:后进前出LIFO(Last InFirst Out)支持操作:入栈 Push,出栈 Pop,读栈顶 Peek,个数 Count
类库中已定义的栈类System.Collections.Stack System.Collections.Generic.Stack<T>
队列: Queue<T>, Queue
特点:前进前出FIFO(First In First Out)支持操作:入队Enqueue,出队Dequeue,读队首Peek,个数Count
类库中已定义的队列类System.Collections.Queue System.Collections.Genric.Queue<T>
有序字典: SortedDictionary<TKey,TValue>,StortedList
特点:键值对集合,有序,按键自动排序, 按键索引值支持的操作:增加Add,删除 Remove ,清空 Clear ,检查存在ContainsKeyContainsValue
属性: 个数Count, 键集合Keys,值Values
链表: LinkedList<T>
特点:节点内存空间不连续,插入,删除速度快,读取速度慢.支持的操作加在头AddFirst加在尾 AddLast 插入前 AddBefore 插入后 AddAfter
查找 Find
相关文章推荐
- java常用的几种数据结构,堆栈,队列,数组,链表,哈希表
- 队列、堆栈与数组、链表的关系与区分
- 队列、堆栈与数组、链表的关系与区分
- 数组、链表、堆栈和队列
- 数组、链表、堆栈和队列
- 数组、链表、堆栈和队列
- 剑指offer-第二章数据结构(数组,字符串,链表,树,栈与队列)及例题
- Lua中使用table实现的其它5种数据结构(数组、链表、队列、集合和包、StringBuild)
- 使用JavaScript的数组实现数据结构中的队列与堆栈
- 数据结构学习---堆栈的动态数组实现及链表实现
- 巧用javascript数组实现数据结构-堆栈与队列
- “数组、堆栈”与“链表、队列”的区别
- 队列、堆栈与数组、链表的关系与区分
- 数据结构学习---堆栈的动态数组实现及链表实现
- 常用数据结构 及 队列、链表、堆栈的区别
- 巧用javascript数组实现数据结构-堆栈与队列
- 目标:完成数组和链表创建队列,完成其余基本数据结构。
- 队列、堆栈与数组、链表的关系与区分
- 队列、堆栈与数组、链表的关系与区分
- 数组链表堆栈和队列