本写作参考《数据结构与算法分析--C语言描述》,linux的list.h文件,以及数组和链表的一些理解
目的如下:
- 简要描述链表和数组为什么重要,具体主要是内存分配原因
- 绘图分析list.h的双向链表,来看看双向链表是如何拓展为栈和队列的
- 分析一下双向链表是如何面向对象的,为什么没写构造的函数
1、链表和数组
链表和数组是对内存的两种分配方式,通常是这样:
数组是一个连续固定的空间,以起始地址为开始,按照数据类型的大小增长。当数组的类型和起始地址确定后,数组的每个单元都是确定的。
CPU可以通过地址总线、数据总线一次访问到要用的存储单元。
链表是不连续的,它的单元由一个数据单元和两个指针构成,每个单元通过左右指针链接起来就是链表。
因此算法上有如下区别:
数组:
1、事先要对表进行估值,浪费空间(因为空间大小是固定的,只考虑C定义下的数组)
2、insert、delete最坏时间是O(N),平均时间是最坏时间的一半,还是O(N)(因为要移动其它数据,数组没有指向)
findKth是O(1)(只需要地址总线的一次查询)
3、一般不用来做链表
链表:
1、内存不是连续的,因此只要申请一个单元,链接起来即可构成新的链表
2、insert、delete时间为O(1)(申请单元后只需改变指向即可)
3、Find为O(N)因为要遍历(其实FindKth也是O(N),访问第几个就要next几次)
栈:
其实是链表这个对象的子对象,把细节隐藏起来,使链表只有表头可见,只提供表头的插入和删除就是栈
队列:
链表尾部插入,头部取出删除就是普通队列,其余部分隐藏。