先赞再看,养成习惯!
链表作为一种常用的数据结构,我们还是有必要了解一下的,如果有不太了解什么是“链表”的可以查看一下之前的文章。今天让我们动手实现一个“双向链表”。
双向链表的节点类
public class Node {
/**
* 数据域
*/
public String data;
/**
* 指针域(指向下一个节点)
*/
public Node next;
/**
* 指针域(指向前一个节点)
*/
public Node pre;
/**
* 构造方法
*/
public Node(String data) {
this.data = data;
}
}
双向链表(带头节点)的基本代码
public class DoubleLinkedList {
// 头节点
private Node herd = new Node("HerdNode");
public Node getHerd() {
return herd;
}
public void setHerd(Node herd) {
this.herd = herd;
}
}
在链表尾部添加节点
public void addAfter(Node newNode) {
// 定义辅助变量,遍历链表使用
Node temp = herd;
while (true){
// 到达列表尾部
if(temp.next == null){
break;
}
// 后移辅助节点
temp = temp.next;
}
// 在链表尾部添加新节点
temp.next = newNode; // 将原链表的尾部节点的下一个指针域指向新节点
newNode.pre = temp; // 将新节点的前一个指针域指向原链表的尾部节点
}
在指定节点内容后插入数据
开始编码前,先看下图,有助于理解代码。
/**
* 在指定节点内容后插入数据
*
* @param nodeData 指定节点的内容(插入到哪个节点后)
* @param newNode 新节点
*/
public void insertAfterNode(String nodeData, Node newNode) {
// 参数校验
if (nodeData == null) {
throw new RuntimeException("入参有误!");
}
// 定义辅助变量,遍历链表使用
Node temp = herd;
// 定义标记,标识找到指定内容的节点
boolean flag = false;
while (true) {
// 到达链表尾部,结束循环。
if (temp == null) {
break;
}
// 找到指定的节点,结束循环。
if (nodeData.equals(temp.data)) {
flag = true;
break;
}
// 将辅助节点后移
temp = temp.next;
}
if (flag) {
// 注:temp代表的是需要在该节点后插入新节点
// 判断是否是在链表尾部添加节点
if (temp.next != null) {
// 将temp节点的下一个节点的前一个指针域,指向新节点。
temp.next.pre = newNode;
// 将新节点的下一个指针域,指向temp节点的下一个节点。
newNode.next = temp.next;
}
// 将temp节点的下一个指针域指向新节点。
temp.next = newNode;
// 将新节点的前一个指针域指向temp节点。
newNode.pre = temp;
} else {
throw new RuntimeException("未找到指定节点无法插入新节点!");
}
}
根据指定节点内容删除节点
为了更好地理解代码,请先看下图。
/**
* 删除指定节点
*
* @param data 指定节点内容(被删除的节点内容)
*/
public void delete(String data) {
// 参数校验
if (data == null) {
throw new RuntimeException("入参有误!");
}
// 定义辅助变量,遍历链表使用
Node temp = herd;
// 定义标记,标识找到指定内容的节点
boolean flag = false;
while (true){
// 到达链表尾,结束循环。
if(temp == null){
break;
}
// 找到待删除的节点
if(data.equals(temp.data)){
flag = true;
break;
}
// 后移辅助节点
temp = temp.next;
}
// 判断是否存待删除的节点
if (flag) {
// 将待删除节点的前一个节点的下一个指针域,指向待删除节点的下一个节点。
temp.pre.next = temp.next;
// 如果是待删除的节点是最后一个节点,就不需要下面这个操作了
if (temp.next != null) {
// 将待删除节点的下一个节点的前一个指针域,指向待删除节点的前一个节点。
temp.next.pre = temp.pre;
}
} else {
System.out.println("未找到要删除的节点!");
}
}
通过上面的代码和图片相信大家对双向链表会有一个自己的认知,修改和查询相对简单,我就不在演示。有问题的大家可以指出来。感觉文章写的还不错的记得点个赞在走哟。