package com.zengwen.linkedlist;
/**
* 不带头节点的双向链表
*/
public class DoubleLinkedListDemo {
public static void main(String[] args) {
Node node1 = new Node(1, "宋江", "及时雨");
Node node2 = new Node(2, "卢俊义", "玉麒麟");
Node node3 = new Node(3, "吴用", "智多星");
Node node4 = new Node(4, "林冲", "豹子头");
DoubleLinkedList doubleLinkedList = new DoubleLinkedList();
/**
* 添加测试(末尾直接)
*/
System.out.println("添加前~~");
doubleLinkedList.list();//遍历链表
doubleLinkedList.addNode(node1);//在节点node1后面添加节点node2
doubleLinkedList.addNode(node2);
System.out.println("添加后~~");
doubleLinkedList.list();//遍历链表
/**
* 添加测试2(按照编号排序)
*/
System.out.println("添加前~~");
doubleLinkedList.list();//遍历链表
doubleLinkedList.addNodeOrder(node1);
doubleLinkedList.addNodeOrder(node2);
doubleLinkedList.addNodeOrder(node4);
doubleLinkedList.addNodeOrder(node3);
System.out.println("添加后~~");
doubleLinkedList.list();//遍历链表
/**
* 修改测试
*/
doubleLinkedList.addNode(node1);
doubleLinkedList.addNode(node2);
doubleLinkedList.addNode(node3);
doubleLinkedList.addNode(node4);
System.out.println("修改前~~");
doubleLinkedList.list();//遍历链表
Node newNode = new Node(2, "卢大大", "小雨子");
doubleLinkedList.updateNode(newNode);
System.out.println("修改后~~");
doubleLinkedList.list();//遍历链表
/**
* 删除测试
*/
doubleLinkedList.addNode(node1);
doubleLinkedList.addNode(node2);
doubleLinkedList.addNode(node3);
doubleLinkedList.addNode(node4);
System.out.println("删除前~");
doubleLinkedList.list();//遍历链表
doubleLinkedList.remove(4);
System.out.println("删除后~");
doubleLinkedList.list();//遍历链表
}
}
/**
* 带head头的双向链表
*/
class DoubleLinkedList {
//初始化一个头节点,头节点不动,不存放具体的数据
private Node head = new Node(0, "", "");
//遍历双向链表的方法
//显示链表【链表】
public void list() {
//判断链表是否为空
if (head.next == null) {
System.out.println("链表为空~");
}
Node temp = head.next;
while (true) {
//判断是否到链表最后
if (temp == null) {
break;
}
//输出节点的信息
System.out.println(temp);
//将temp后移
temp = temp.next;
}
}
/**
* 修改双向链表一个节点的内容(和单向链表节点修改基本一致)
*
* @param newNode
*/
public void updateNode(Node newNode) {
//判断是否为空
if (head.next == null) {
System.out.println("链表为空~~");
return;
}
//找到需要修改的节点,根据no编号
//定义一个辅助变量
Node temp = head.next;
boolean flag = false;//表示是否找到该节点
while (true) {
if (temp == null) {
break;//已经遍历完链表
}
if (temp.no == newNode.no) {
//找到
flag = true;
break;
}
temp = temp.next;
}
//根据flag判断是否找到要修改的节点
if (flag) {
temp.name = newNode.name;
temp.nickName = newNode.nickName;
} else {
System.out.printf("没有找到编号%d的节点,不能修改\n", newNode.no);
}
}
/**
* 添加一个节点到双向链表的最后
*
* @param newNode
*/
public void addNode(Node newNode) {
Node temp = head;
//遍历链表找到最后
while (true) {
//找到链表的最后
if (temp.next == null) {
break;
}
//如果没有找到最后,将temp后移
temp = temp.next;
}
temp.next = newNode;//将最后节点的next指向新节点
newNode.pre = temp;//将新节点的pre指向最后节点
}
/**
* 双向链表的第二种添加方式,按照编号顺序
*
* @param newNode
*/
public void addNodeOrder(Node newNode) {
//如果链表为空
if (head.next == null) {
head.next = newNode;//将最后节点的next指向新节点
newNode.pre = head;//将新节点的pre指向最后节点
return;
}
Node temp = head;
boolean flag = false;//flag标志添加的编号是否存在,默认为false
while (true) {
if (temp.no > newNode.no) {//位置找到,就在temp的前面插入
break;
} else if (temp.next != null && (temp.next.no == newNode.no)) {//说明编号已经存在
flag = true;
break;
}
if (temp.next == null) {//temp已经在链表的最后
temp.next = newNode;//将最后节点的next指向新节点
newNode.pre = temp;//将新节点的pre指向最后节点
return;
}
temp = temp.next;//后移
}
//判断flag
if (flag) {
System.out.println("已经存在该编号,添加失败~~");
} else {
temp.pre.next = newNode;
newNode.pre = temp.pre.next;
newNode.next = temp;
temp.pre = newNode;
}
}
/**
* 删除节点
*
* @param no
*/
//对于双向链表,我们可以直接找到要删除的节点,找到后“自我删除”
public void remove(int no) {
//判断当前链表是否为空
if (head.next == null) {
System.out.println("链表为空,无法删除");
return;
}
Node temp = head.next;//辅助指针
boolean flag = false;//标志是否找到待删除的节点
while (true) {
if (temp == null) {//已经到链表的最后
break;
}
if (temp.no == no) {
//找到待删除节点
flag = true;
break;
}
temp = temp.next;//temp后移,遍历
}
if (flag) {//找到
temp.pre.next = temp.next;//红色线
if (temp.next != null) { //如果是最后一个节点就不需要执行下面这句话
temp.next.pre = temp.pre;//粉色线
}
}
}
}
class Node {
int no;//编号
String name;//姓名
String nickName;//昵称
Node next;//指向下一个节点,默认为null
Node pre;//指向前一个节点,默认为null
public Node(int no, String name, String nickName) {
this.no = no;
this.name = name;
this.nickName = nickName;
}
@Override
public String toString() {
return "Node[" +
"no=" + no +
", name='" + name + '\'' +
", nickName='" + nickName + "]";
}
}