- 节点类(以内部类形式使用)
链表中内部类和嵌套类的区别:
https://blog.csdn.net/WelcomeSpring/article/details/79430546
private class Node<E> {
private E date;
private Node next;
private Node prev;
public Node() {
date = null;
next = null;
prev = null;
}
public Node(E date) {
this.date = date;
}
public Node(E date, Node next, Node prev) {
this.date = date;
this.next = next;
this.prev = prev;
}
public E getData() {
return date;
}
public void setData(E data) {
this.date = data;
}
public Node getNext() {
return next;
}
public void setNext(Node next) {
this.next = next;
}
public Node getprev() {
return prev;
}
public void setprev(Node prev) {
this.prev = prev;
}
}
- 双链表的实现
链表接口见https://blog.csdn.net/qq_44467578/article/details/103946997
package 数据结构;
public class myLinkedList<E> implements List<E> {
private Node<E> head = new Node<>();
private int size = 0;
@Override
public int getSize() {
return size;
}
@Override
public boolean isEmploy() {
if (head.getNext() == null)
return true;
else
return false;
}
@Override
public boolean contains(E val) {
Node<E> nNode = head.getNext();
while (nNode != null) {
if (nNode.getData() == val)
return true;
else
nNode = nNode.getNext();
}
return false;
}
@Override
public boolean headadd(E val) {
Node<E> node = new Node(val);
Node<E> nNode = head.getNext();
if (isEmploy()) {
head.setNext(node);
node.setprev(head);
size++;
} else {
head.setNext(node);
nNode.setprev(node);
node.setNext(nNode);
node.setprev(head);
size++;
}
return true;
}
@Override
public boolean tailadd(E val) {
Node<E> node = new Node(val);
Node<E> pNode = head;
while (pNode.getNext() != null) {
pNode = pNode.getNext();
}
pNode.setNext(node);
node.setprev(pNode);
node.setNext(null);
size++;
return true;
}
public boolean remove() {
Node<E> node = head;
while (node.getNext() != null)
node = node.getNext();
node.getprev().setNext(null);
node = null;
size--;
return true;
}
@Override
public int indexOf(E val) {
int i = 0;
Node<E> nNode = head.getNext();
while (nNode != null) {
if (val == nNode.getData())
return i;
else {
nNode = nNode.getNext();
i++;
}
}
return -1;
}
@Override
public boolean insert(int i, E val) {
if (i == 0)
headadd(val);
if (i == size)
tailadd(val);
else if(i>0&i<size) {
Node<E> node = new Node<>(val);
Node<E> pNode = head.getNext();
for (int j = 0; j < i; j++) {
pNode = pNode.getNext();
}
pNode.getprev().setNext(node);
pNode.setprev(node);
node.setprev(pNode.getprev());
node.setNext(pNode);
size++;
return true;
}
return false;
}
@Override
public boolean remove(int i) {
Node<E> pNode = head.getNext();
if (i == size - 1) {
return remove();
}
for (int j = 0; j < i; j++) {
pNode = pNode.getNext();
}
pNode.getprev().setNext(pNode.getNext());
pNode.getNext().setprev(pNode.getprev());
pNode = null;
size--;
return true;
}
@Override
public boolean remove(E val) {
Node<E> nNode = head.getNext();
while (nNode.getNext() != null) {
if (nNode.getData() == val) {
nNode.getprev().setNext(nNode.getNext());
nNode.getNext().setprev(nNode.getprev());
nNode = null;
size--;
return true;
} else
nNode = nNode.getNext();
}
if(nNode.getData() == val)
return remove();
return false;
}
@Override
public void replace(int i, E val) {
Node<E> pNode = head;
for (int j = 0; j < i; j++) {
pNode = pNode.getNext();
}
pNode.setData(val);
}
@Override
public Object getval(int i) {
Node<E> pNode = head;
for (int j = 0; j <= i; j++) {
pNode = pNode.getNext();
}
return pNode.getData();
}
@Override
public void print() {
if (isEmploy())
System.out.println("为空");
else {
Node<E> pNode = head;
for (int j = 0; j < size; j++) {
pNode = pNode.getNext();
System.out.print(pNode.getData() + "> ");
}
}
}
public void reverseList() {
Node<E> node, nNode;
node = head.getNext();
node.setprev(node.getNext());
node = node.getNext();
nNode = node.getNext();
head.getNext().setNext(null);
while (nNode != null) {
node.setNext(node.getprev());
node.setprev(nNode);
node = node.getprev();
nNode = node.getNext();
}
node.setNext(node.getprev());
node.setprev(head);
head.setNext(node);
}
private class Node<E> {
private E date;
private Node next;
private Node prev;
public Node() {
date = null;
next = null;
prev = null;
}
public Node(E date) {
this.date = date;
}
public Node(E date, Node next, Node prev) {
this.date = date;
this.next = next;
this.prev = prev;
}
public E getData() {
return date;
}
public void setData(E data) {
this.date = data;
}
public Node getNext() {
return next;
}
public void setNext(Node next) {
this.next = next;
}
public Node getprev() {
return prev;
}
public void setprev(Node prev) {
this.prev = prev;
}
}
}
- 双链表的实例
package 数据结构;
public class Main {
public static void main(String[] args) {
myLinkedList<Integer> LL=new myLinkedList<>();
LL.headadd(6);
LL.tailadd(7);
LL.insert(2, 8);
LL.remove(1);
LL.print();
System.out.println();
LL.reverseList();
LL.print();
System.out.println();
System.out.print(LL.getSize()+" "+LL.getval(1)+" "+LL.contains(7)+" "+
LL.indexOf(7)+" "+LL.isEmploy());
}
}
- 扩展
双链表去掉前驱指针即为单链表
将尾节点的后继指针指向头节点即为循环链表
链表的转置有三个地方需要修改:
*尾节点变头节点:尾节点的前驱指针指向null,后继指针指向前驱节点
*头节点变尾节点:头节点的前驱指针指向后继节点,后继指针指向null
*中间节点:前驱后继对换