前言
链表是一种数据结构,和数组同级,如Java中使用的ArrayList,其实现原理是数组,而LinkedList是链表,链表在循环遍历时效率不高,但在插入删除时优势却很明显,学习好链表也是夯实基础的重要,在算法题中链表也有着举足轻重的地位。本系列文章会就一些经典的算法题入手,剖析各数据结构以及题解的思想~
一、链表数据结构剖析
链表是通过指针串联在一起的线性结构,每一个节点由两部分组成,数据域和指针域,顾名思义,数据域是存放节点信息数据的区域(好比是房子),指针域就是指针指向下一节点的区域(好比是房子前的路牌),而链接的入口点称为列表的头结点也就是head。
链表类型
上面阐述的仅仅是一种最为简单普遍的单链表类型,链表还有以下常见的类型:
1.双链表
双链表是指既指向下一节点又能指向上一节点的一种链表结构
2.循环链表
在普通单链表中,尾结点始终指向空,而头结点是没有结点指向它,循环链表就是将头尾结点像其他节点一般串联起来的一种链表结构:
链表存储方式
数组在内存中是连续分布的
链表中各节点是散列分布的
链表的定义(Java)
关于链表的定义,可以去看风吹草东动的博客:自定义单链表
一定要能手写单链表定义!!!
应用篇(Day1)
移除链表元素(Leetcode:203)
题目:
思路:
如何移除一个节点呢?
其实很简单,只需要从链表头节点开始,知道下一节点为null,将其中不满足要求的节点的上一节点指向这个节点的下一个节点,那么就等于断了这个节点的“通路”,而Java得GC回收机制会自动回收节点资源,所以不必手动回收,下面我们看看示例代码:
示例代码:
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode removeElements(ListNode head, int val) {
//头结点若为空,那么就无需判断了
if(head==null)
return null;
//删除的节点可能是头结点,故需要在头结点前先确定一个首节点
ListNode dummy=new ListNode(-1,head);
ListNode prev=dummy;
ListNode curr=head;
while(curr!=null){
if(curr.val==val){
//需要删除
prev.next=curr.next; //删除节点的上一节点指向删除节点的下一节点
}else{
prev=curr; //将当前节点置为上一个节点,然后移动下一个节点
}
curr=curr.next;
}
return dummy.next;
}
}