单向链表的构建
在 Java 中单向链表主要是利用类来进行构造,且一个链表通常是有多个节点,节点与节点相连形成一种链式结构。(如下图)
代码如下
public class CreateLinked {
static class LinkedNode {
public int val;
public LinkedNode next;
public LinkedNode(int val) {
this.val = val;
this.next = null;
}
@Override
public String toString() {
return "NewNode{" +
"val = " + val +
", next = " + next +
'}';
}
}
public static void main(String[] args) {
// 1. 先创建一个头结点
LinkedNode head = new LinkedNode(1);
// 2. 创建链表中其他节点
LinkedNode n2 = new LinkedNode(2);
LinkedNode n3 = new LinkedNode(3);
// 3. 构建链表
head.next = n2;
n2.next = n3;
// 4. 打印看看
System.out.println(head);
}
}
运行结果
NewNode{val = 1, next = NewNode{val = 2, next = NewNode{val = 3, next = null}}}
单链表的添加元素
在链表插入元素之前需要引入一个头指针 head 它的 next 指针一般指向的是一个链表中的首元素。
分析
在链表的插入中存在三种情况,如下:
(1)头部插入
将待插入节点的 next 指向第一个节点
curr.next = head.next
将 head 节点再指向待插入节点
head.next = curr
(2)中间插入
需要遍历整个链表找到待插入节点的前一个节点之后再进行插入操作
需要将待插入节点的 next 指向后一个
curr.next = pre.next;
再将待插入节点的前一个节点指向待插入节点
pre.next = curr;
(3)尾部插入
循环遍历将节点 pre 指向最后一个节点
在链表中最后一个节点直接指向新节点
pre.next = curr;
代码实现
/**
* 链表的插入方法
*
* @param head 待插入头结点
* @param newNode 待插入节点
* @param postition 插入位置
* @return 该链表
*/
public static Node insertNode(Node head, Node newNode, int postition) {
if (head == null) {
// 说明链表的头结点即为待插入节点
return newNode;
}
// 求出链表长度
int size = getLinkedLength(head);
// 限制插入位置的范围
if (postition > size + 1 || postition < 1) {
return head;
}
// 当插入位置为 1 时,即需要在链表头部进行插入
if (postition == 1) {
newNode.next = head;
head = newNode;
return head;
}
int count = 1;
Node preNode = head;
// 需要找到该元素的前一个元素
while (count < postition - 1) {
preNode = preNode.next;
count++;
}
newNode.next = preNode.next;
preNode.next = newNode;
return head;
}
单链表的删除元素
分析
链表中删除元素依旧存在三种情况
(1)删除头部元素
直接让 head 节点指向下一个节点即可
head = head.next;
(2)删除中间元素
让待删除节点的前一个节点直接指向待删除节点的后一个节点
pre.next = pre.next.next;
(3)删除尾部元素
将最后一个节点的前一个节点直接指向 null 即可
pre.next = null;
代码实现
/**
* 删除节点
* @param head 链表头节点
* @param postition 待删除链表位置
*/
public static Node deleteNode(Node head, int postition) {
// 链表为空,无法删除
if (head == null) {
return head;
}
// 链表长度
int size = getLinkedLength(head);
// 链表越界错误
if (postition < 1 || postition > size) {
return head;
}
// 从头部删除元素
if (postition == 1) {
// return head.next;
head = head.next;
return head;
}
Node temp = head;
int count = 1;
while (count < postition - 1) {
temp = temp.next;
count++;
}
temp.next = temp.next.next;
return head;
}
双向链表的构建
与单向链表不同的是,双向链表多一个可以指向前一个节点的指针 prev
双向链表的插入和删除
插入