java双向链表任意位置元素的插入
一、难点剖析
- 相比于单向链表,双向链表的逻辑更强,同时在增、删、查、改的时候也为我们提供了比单向链表更多的选择。
- 在这里定义头节点为head,尾节点为last。
- 在插入时,要考虑双向链表为空的情况下插入、在头节点,尾节点插入时、插入位置不合法时的情况。
- 在测试代码时,应该测试头节点,尾节点和中间节点的元素插入。避免出现bug。
- 如果不懂,就多画图理解!!!
二、示意图讲解
- 头插法
- 尾插法
- 中间任意位置插入
三、代码实现
public class huashanzhizai {
public static void main(String[] args) {
MyLinkedList myLinkedList = new MyLinkedList();
System.out.println("****头插法****");
myLinkedList.addFirst(1);
myLinkedList.addFirst(2);
myLinkedList.addFirst(3);
myLinkedList.disPlay();
System.out.println("****尾插法****");
myLinkedList.addLast(4);
myLinkedList.addLast(5);
myLinkedList.addLast(6);
myLinkedList.disPlay();
System.out.println("****任意位置插入****");
myLinkedList.addIndex(0, 3);//头节点插入
myLinkedList.disPlay();
myLinkedList.addIndex(7, 6);//尾节点插入
myLinkedList.disPlay();
myLinkedList.addIndex(4, 4);//中间任意位置插入
myLinkedList.disPlay();
}
}
class MyLinkedList {
Node head;//定义双向链表的头节点
Node last;//定义双向链表的尾节点
//打印双向链表
public void disPlay() {
Node cur = this.head;
while (cur != null) {
System.out.print(cur.val + " ");
cur = cur.next;
}
System.out.println();
}
//求双向链表的长度(之后addIndex代码会用到)
public int size() {
int count = 0;
Node cur = this.head;
while (cur != null) {
count++;
cur = cur.next;
}
return count;
}
//头插法
public void addFirst(int data) {
Node node = new Node(data);//定义一个用作插入的节点
//1.假设双向链表为空
if (this.head == null) {
this.head = node;
this.last = node;
} else {
//2.双向链表不为空的情况下
//不懂请看上面的图解,就很简单了
node.next = this.head;
this.head.prev = node;
this.head = node;
}
}
//尾插法(与头插法类似)
public void addLast(int data) {
//定义一个用作插入的节点
Node node = new Node(data);
//1.假设双向链表为空
if (this.head == null) {
this.head = node;
this.last = node;
} else {
//2.双向链表不为空的情况下
//不懂请看上面的图解,就很简单了
last.next = node;
node.prev = last;
last = node;
}
}
//在任意位置插入
public void addIndex(int index, int data) {//形参index为插入元素位置,data为插入的数值
//定义一个用作插入的节点
Node node = new Node(data);
Node cur = this.head;//定义一个cur用作遍历双向链表
//1、判断插入位置的合法性
if (index < 0 || index > size()) {
System.out.println("插入位置不合法!!!");
return;
}
//2、假设插入位置为头结点的情况下,即就是头插法
if (index == 0) {
addFirst(data);//调用头插法代码
return;
}
//3、假设插入位置为尾结点的情况下,即就是尾插法
if (index == size()) {
addLast(data);//调用尾插法代码
return;
}
//4、在中间任意位置的情况下
while (index != 0) {
cur = cur.next;
index--;
}
//不懂请看上面的图解,就很简单了
//核心代码
node.next = cur;
node.prev = cur.prev;
cur.prev = node;
node.prev.next = node;
}
}
//双向链表的节点结构
class Node {
int val;
Node prev;
Node next;
Node(int val) {
this.val = val;
}
}
- 执行结果
****头插法****
3 2 1
****尾插法****
3 2 1 4 5 6
****任意位置插入****
3 3 2 1 4 5 6
3 3 2 1 4 5 6 6
3 3 2 1 4 4 5 6 6
四、原理分析
- 请见上代码!!!