例题:https://leetcode-cn.com/problems/design-linked-list/
单链表
成员变量
1 2 3 4
| Node head = null; int size; or int index;
|
内部节点类
1 2 3 4 5 6 7
| class Node{ int val; Node next; public Node(int val){ this.val = val; } }
|
插入新的头节点
- Node node = new Node(val);
- node.next = head;
- head = node;
插入新的节点(以在头节点及其下一个节点间插入节点为例)
- Node node = new Node(val);
- node.next = head.next;
- head.next = node;
注意:在头部插入节点的操作和此操作不同,在大多数时候需要为此写一个if进行特殊操作
为了使二者的操作统一,可以利用虚拟头结点 dummyHead ,dummyHead.next 即为
实际头结点 head,这样插入节点的操作就统一了,最后 return dummyHead.next 即可
删除节点
- 将该节点的上一个节点的next指向该节点的下一个节点或null
- 其实也就是相当于跳过该节点
- 删除头结点,只需要将head 下移即可。head = head.next
遍历链表(下标从0开始)
1 2 3 4 5
| Node node = head; for(int i = 0; i<size; i++){ System.out.println(node.val); node = node.next; }
|
双链表
成员变量
1 2
| Node head = null; int index = -1;
|
内部节点类
1 2 3 4 5 6 7 8
| class Node{ int val; Node next = null; Node pre = null; public Node(int val){ this.val = val; } }
|
插入头节点
1 2 3 4 5 6 7 8
| if(head != null){ Node node = new Node(val); node.next = head; node.pre = null; head.pre = node; } head = node;
|
插入节点(非头非尾)
1 2 3 4 5 6
| Node node = new Node(val); node.next = tmp; node.pre = tmp.pre; tmp.pre.next = node; tmp.pre = node;
|
插入尾节点
1 2 3 4 5
| Node node = new Node(val); node.next = null; node.pre = tmp; tmp.next = node;
|
注意:双链表除了有插入头结点这个特殊情况外,还有插入尾结点这个特殊情况。
此时我们可以利用虚拟头结点和虚拟尾结点来实现双链表插入操作的统一
删除头结点
1 2 3 4 5
| if(head.next == null){ head == null; }else{ head = head.next; }
|
删除结点(非头非尾)
1 2 3
| node.pre.next = node.next; node.next.pre = node.pre;
|
删除尾结点
1 2 3 4 5 6
| if(node == head){ head = null; }else{ node.pre.next = null; }
|
遍历操作和单链表相同,只不过还可以从尾巴遍历回去