一、单链表
单链表的结点结构如下图所示。data 为数据域,存放数据元素;next为指针域,存放其后继结点的地址。
class ListNode{
int data;
ListNode next;
ListNode(int x){data=x;}
}
优缺点
优点:单链表不需要连续的存储单元,且插入和删除不需要大量移动元素。
缺点:顺序表可以随机查找某个固定下标的值,链表则不适合查找,只能从表头开始遍历。
头结点
为了操作上的方便,有时会在单链表第一个结点之前附加一个结点,称为头结点。头结点的数据域可以自由设置,它可以不设置任何信息,也可以记录表长。
这样做的好处是将表首结点的处理与其他结点统一起来,操作方便。二、双链表
单链表只能从前向后遍历。双链表的结构如下:
class ListNode{
int data;
ListNode prior,next;
ListNode(int x){data=x;}
}
三、循环链表
循环单链表最后一个结点的指针不是Null,而是指向第一个结点,从而整个链表形成一个环。
循环双链表第一个结点的prior指针还要指向表尾结点。
注意:头结点不是第一个结点,是在第一个结点之前增加的没有数据的结点,头结点不是必需的。
双链表的优势在于可以查找当前结点的上一个结点。但它仍然不能方便的对表尾结点进行操作,只有双循环链表可以快速定位到表尾结点。
如果要频繁的插入、删除表尾结点,采用单链表是无法实现的。即使设置一个指针指向单列表的最后一个结点,但删除时我们无法得知它的上一个结点,所以还是得从头开始遍历。所以可以采用双链表来实现。要么使用双循环链表,要么设置一个指针指向表尾结点。
扩展(java集合之LinkedList)
- LinkedList底层维护了一个双向链表。
- LinkedList中维护两个属性first和last分别指向首节点和尾节点。
所以 LinkedList查询慢,增删快,但是如果操作的是首尾元素,速度也是极快的。