目录
一、应用场景
使用带head头的双向链表实现 –水浒英雄排行榜
二、使用单链表实现的缺点
-
单向链表,查找的方向只能是一个方向,而双向链表可以向前或者向后查找。
-
单向链表不能自我删除,需要靠辅助节点 ,而双向链表,则可以自我删除,所以前面我们单链表删除时节点,总是找到temp,temp是待删除节点的前一个节点。
三、思路分析
四、操作双链表代码示例
public class DoubleLinkedList {
// 定义一个头节点
private final DoubleHeroNode head = new DoubleHeroNode(0,"", "");
/**
*
* @Description 向链表中添加元素
* @param node 添加的元素
*/
public void addHeroMsg(DoubleHeroNode node) {
DoubleHeroNode temp = head;
while (Optional.ofNullable(temp.getNext()).isPresent()) {
temp = temp.getNext();
}
temp.setNext(node);
node.setPre(temp);
}
/**
*
* @Description 向链表中添加元素 -- 有序
* @param node 添加的元素
*/
public void addHeroMsgByOrder(DoubleHeroNode node) {
DoubleHeroNode temp = head;
boolean flag = false;
while (true) {
if (Optional.ofNullable(temp.getNext()).isEmpty()) {
break;
}
// 通过编号排序
if (temp.getNext().getNo() > node.getNo()) {
break;
}
// 判断编号是否存在
if (temp.getNext().getNo() == node.getNo()) {
flag = true;
break;
}
temp = temp.getNext();
}
if (flag){
System.out.println("编号" + node.getNo() + "已存在, 不可重复加入哦~");
return;
}
node.setNext(temp.getNext());
node.setPre(temp);
if (Optional.ofNullable(temp.getNext()).isPresent())
node.getNext().setPre(node);
temp.setNext(node);
}
/**
*
* @Description 修改数据
* @param node 修改的成员信息
*/
public void updateHeroMsg(DoubleHeroNode node) {
if (Optional.ofNullable(head.getNext()).isEmpty()) {
System.out.println("链表中占无数据哦~");
return;
}
DoubleHeroNode temp = head;
boolean flag = false;
while (true) {
if (Optional.ofNullable(temp.getNext()).isEmpty()) {
flag = true;
break;
}
if (temp.getNext().getNo() == node.getNo()) {
break;
}
temp = temp.getNext();
}
if (flag) {
System.out.println("编号为" + node.getNo() + "的信息不存在!!!");
return;
}
temp.getNext().setName(node.getName());
temp.getNext().setNickname(node.getNickname());
}
/**
*
* @Description 删除数据
* @param nodeId 删除的元素信息
*/
public void deleteHeroMsg(int nodeId) {
if (Optional.ofNullable(head.getNext()).isEmpty()) {
System.out.println("链表中占无数据哦~");
return;
}
DoubleHeroNode temp = head.getNext();
boolean flag = false;
while (true) {
if (Optional.ofNullable(temp).isEmpty()) {
flag = true;
break;
}
if (temp.getNo() == nodeId) {
break;
}
temp = temp.getNext();
}
if (flag) {
System.out.println("编号为" + nodeId + "的信息不存在!!!");
return;
}
temp.getPre().setNext(temp.getNext());
if (Optional.ofNullable(temp.getNext()).isPresent())
temp.getNext().setPre(temp.getPre());
}
/**
*
* @Description 显示链表中的元素
*/
public void showHeroMsg() {
DoubleHeroNode next = head.getNext();
if (Optional.ofNullable(next).isEmpty()) {
throw new RuntimeException("链表中的元素为空哦~");
}
while (Optional.ofNullable(next).isPresent()) {
System.out.println(next);
next = next.getNext();
}
}
}
五、单元测试
@Test
public void testDoubleLinkedList() {
// 创建节点
DoubleHeroNode node_1 = new DoubleHeroNode(1, "宋江", "及时雨");
DoubleHeroNode node_2 = new DoubleHeroNode(2, "卢俊义", "玉麒麟");
DoubleHeroNode node_3 = new DoubleHeroNode(3, "吴用", "智多星");
DoubleHeroNode node_4 = new DoubleHeroNode(4, "林冲", "豹子头");
// 创建一个双向链表
DoubleLinkedList linkedList = new DoubleLinkedList();
linkedList.addHeroMsg(node_1);
linkedList.addHeroMsgByOrder(node_3);
linkedList.addHeroMsgByOrder(node_4);
linkedList.addHeroMsgByOrder(node_2);
System.out.println("添加后的成员信息~~~~~~~~~~~~~~~~");
linkedList.showHeroMsg();
// 修改成员信息
DoubleHeroNode node_5 = new DoubleHeroNode(4, "公孙胜", "入云龙");
linkedList.updateHeroMsg(node_5);
System.out.println("修改后的成员信息~~~~~~~~~~~~~~");
linkedList.showHeroMsg();
// 删除成员信息
linkedList.deleteHeroMsg(2);
System.out.println("删除后的成员信息~~~~~~~~~~~~~~");
linkedList.showHeroMsg();
}
六、运行结果