表按存储形式分为顺序存储表和链表,这里讨论链表的不同实现方式。
通常我们对链表的访问集中在表头结点,表尾结点上,不同的创建方式对应着不同的访问方式和效率。创建链表时一般采用以下几种方式:
单链表
- 普通的单链表
这种链表在插入结点时要判断head是否为空,因为当链表为空和不空时,在结尾处插入结点的代码是不同的。为了简化这种情况,可以使用带头结点的单链表
- 带头结点的单链表
采用这种形式的结构时,对链表中的元素的插入操作的代码就统一了,不需要判断链表是否为空的代码,但是如果要在链表的最后一个结点后插入一个新结点或删除最后一个结点,就需要从head开始遍历整个链表,为了提高对结尾结点的操作效率,引入了带尾指针的单链表
- 带头结点和尾指针的单链表
其可以方便的解决上面的在最后一个结点后面添加新的结点这个问题,但是当要删除最后一个结点时,还是要从head开始遍历链表,因为如果根据tail删除的话,其之前的结点的next无法得到,也就没法置其为NULL。
双链表
- 普通的双向链表
循环链表
- 带头结点的循环链表
可见,在链表的尾部插入一个结点时,仍然需要遍历整个链表,为了方便这种操作,可采用带尾指针的循环链表
- 带尾指针的循环链表
这种链表就可以很方便的访问链表的首节点和尾结点
带头结点的双向循环链表
- 带头结点的双向循环链表
(空的带头结点双向循环链表)