双向链表是很多高级数据结构和算法的基础,比如队列、栈、图、哈希...
以下demo基本包含了双向链表的增删改查:
节点类 DoubleLinkedNode.java
/**
* 双向链表节点
*/
public class DoubleLinkedNode implements Serializable {
//节点值
public Integer value;
//前置节点
public DoubleLinkedNode pre;
//下一个节点
public DoubleLinkedNode next;
public DoubleLinkedNode(Integer value) {
this.value = value;
}
@Override
public String toString() {
return String.valueOf(value);
}
}
双向链表数据结构和算法类 DoubleLinked.java
/**
* 双向链表
*/
public class DoubleLinked {
//头结点
DoubleLinkedNode head;
//链表长度
int size;
/**
* 判空
*
* @return
*/
public Boolean isEmpty() {
return size == 0;
}
/**
* 遍历节点-从头到尾
*/
public void show() {
if (isEmpty()) {
System.out.println("数据为空!");
return;
}
DoubleLinkedNode temp = head;
while (temp != null) {
System.out.printf(temp + ", ");
temp = temp.next;
}
System.out.println();
}
/**
* 添加节点
*
* @param node 节点
*/
public void add(DoubleLinkedNode node) {
//第一个元素,初始化头结点
if (size == 0) {
head = node;
} else {
//第一个之后的元素
DoubleLinkedNode temp = head;
while (temp.next != null) {
temp = temp.next;
}
temp.next = node;
node.pre = temp;
}
size++;
}
/**
* 查找元素
*
* @param value 值
* @return 节点对象
*/
public DoubleLinkedNode getByValue(Integer value) {
DoubleLinkedNode temp = head;
while (temp != null) {
if (value.equals(temp.value)) {
System.out.println("找到了: " + temp);
return temp;
}
temp = temp.next;
}
return null;
}
/**
* 删除节点
*
* @param value 节点值
* @return
*/
public Boolean removeByValue(Integer value) {
if (getByValue(value) == null) {
System.out.println("未找到value为: " + value + "的数据!");
return false;
}
DoubleLinkedNode temp = head;
while (temp != null) {
if (value.equals(temp.value)) {
//这里要先设置前置节点
if (temp.next != null) {
//处理最后一个节点
temp.next.pre = temp.pre;
}
if (temp.pre != null) {
temp.pre.next = temp.next;
} else {
//删除的是头节点
head = temp.next;
}
size--;
return true;
}
temp = temp.next;
}
return false;
}
/**
* 删除元素
*
* @param index 节点位置
* @return
*/
public Boolean removeByIndex(int index) {
int i = 0;
DoubleLinkedNode temp = head;
while (temp != null) {
if (i == index) {
//这里要先设置前置节点
if (temp.next != null) {
//处理最后一个节点
temp.next.pre = temp.pre;
}
if (temp.pre != null) {
temp.pre.next = temp.next;
} else {
//删除的是头节点
head = temp.next;
}
size--;
return true;
}
i++;
temp = temp.next;
}
return false;
}
/**
* 修改节点
*
* @param node 节点实例
* @return
*/
public Boolean update(DoubleLinkedNode node) {
if (node == null || node.value == null) {
System.out.println("修改数据为空!");
return false;
}
DoubleLinkedNode findNode = getByValue(node.value);
if (findNode == null) {
System.out.println("修改数据不存在!");
return false;
}
findNode.value = node.value;
return true;
}
/**
* 获取第index个值
*
* @param index 位置
* @return 节点实例
*/
public DoubleLinkedNode getIndex(int index) {
int i = 0;
DoubleLinkedNode temp = head;
while (temp != null) {
if (i == index) {
return temp;
}
i++;
temp = temp.next;
}
return null;
}
/**
* 获取链表长度
*
* @return
*/
public int size() {
return size;
}
/**
* 获取倒数第x个元素
* 原理-先让前一个指针先走x步
*
* @param x
* @return
*/
public DoubleLinkedNode getBack(int x) {
int i = 0;
DoubleLinkedNode temp = head;
DoubleLinkedNode s = head;
while (temp != null) {
if (i >= x) {
s = s.next;
}
i++;
temp = temp.next;
}
return s;
}
/**
* 获取中间节点
* 原理-快慢指针,快一倍
*
* @return
*/
public DoubleLinkedNode getMid() {
DoubleLinkedNode temp = head;
DoubleLinkedNode s = head;
while (temp != null && temp.next != null) {
//慢指针
s = s.next;
//快指针
temp = temp.next.next;
}
return s;
}
public static void main(String[] args) {
DoubleLinked doubleLinked = new DoubleLinked();
//初始化链表
System.out.println("数组...");
int[] arr = {7, 3, 8, 10, 12, 5, 1, 9, 2, 6, 4};
System.out.println(Arrays.toString(arr));
for (int value : arr) {
doubleLinked.add(new DoubleLinkedNode(value));
}
System.out.println("遍历节点...");
// doubleLinked.show();
doubleLinked.show();
// System.out.println(doubleLinked.size());
// doubleLinked.removeByValue(2);
// doubleLinked.show();
// doubleLinked.removeByIndex(9);
// doubleLinked.show();
// System.out.println(doubleLinked.getIndex(9));
// System.out.println(doubleLinked.size());
System.out.println(doubleLinked.getBack(2));
System.out.println(doubleLinked.getMid());
// System.out.println(doubleLinked.size());
}
}