动态数组的缺点
- 内存大量浪费
概念
链表是一种链式存储的线性表,所有元素的内存地址不一定是连续的。
Java 实现都是类
单链表
最后一个结点的next 是null
单向循环链表
最后一个结点的next 不是null 指向第一个结点
有环 快慢指针
虚拟头结点
双向链表
Node创建有 prev next 2个Node类型 而且 头结点 的 prev 是null 尾结点的next 是null
双向循环列表
头结点 prev 指向
尾结点 next 指向 头结点
双向链表vs动态数组
练习
删除链表中的节点
直接替换数据。不用找节点 改指针
public class _237_删除链表中的节点 {
public void deleteNode(ListNode node) {
node.val = node.next.val;
node.next = node.next.next;
}
}
反转链表
递归反转
先用2个元素 想想
在用3个 4个 其实递归 是先获取最后一个结点 然后倒数第二个切换 转向 就是指向
public ListNode reverseList(ListNode head) {
if (head == null || head.next == null) return head;
ListNode newHead = reverseList(head.next);
head.next.next = head;
head.next = null;
return newHead;
}
迭代反转
public ListNode reverseList2(ListNode head) {
if (head == null || head.next == null) return head;
ListNode newHead = null;
while (head != null) {
ListNode tmp = head.next;
head.next = newHead;
newHead = head;
head = tmp;
}
return newHead;
}
判断有环
public boolean hasCycle(ListNode head) {
if (head == null || head.next == null) return false;
ListNode slow = head;
ListNode fast = head.next;
while (fast != null && fast.next != null) {
slow = slow.next;
fast = fast.next.next;
if (slow == fast) return true;
}
return false;
}