线性结构-链表

119 阅读1分钟

动态数组的缺点

  • 内存大量浪费

概念

链表是一种链式存储的线性表,所有元素的内存地址不一定是连续的。

Java 实现都是类

单链表

最后一个结点的next 是null

image.png

单向循环链表

最后一个结点的next 不是null 指向第一个结点

image.png

有环 快慢指针

虚拟头结点

image.png

双向链表

Node创建有 prev next 2个Node类型 而且 头结点 的 prev 是null 尾结点的next 是null image.png

双向循环列表

头结点 prev 指向

尾结点 next 指向 头结点

image.png

双向链表vs动态数组

image.png

练习

删除链表中的节点

image.png 直接替换数据。不用找节点 改指针

public class _237_删除链表中的节点 {
	
	public void deleteNode(ListNode node) {
		node.val = node.next.val;
		node.next = node.next.next;
    }
}

反转链表

image.png

递归反转

先用2个元素 想想

在用3个 4个 其实递归 是先获取最后一个结点 然后倒数第二个切换 转向 就是指向

image.png

image.png

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;
    }

迭代反转

image.png

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;
    }

判断有环

image.png

image.png

image.png

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;
    }