下面是定义Node类,双链表和单链表是差不多的,只是双链表的对象中多了一个prev的概念,prev是该节点的前一个节点,next和单链表一个代表着该节点的下一个节点。
一下是双链表的定义类和对双链表操作的一些方法,
class Node {
public int data;
public Node prev;
public Node next;
public Node() {
}
public Node(int data) {
this.data = data;
}
public Node head;
public Node tail;
//头插法
public void addFirst(int data) {
Node node = new Node(data);
if (this.head == null) {
this.head = node;
this.tail = node;
return;
}
node.next = this.head;
this.head.prev = node;
this.head = node;
}
//尾插法
public void addLast(int data) {
Node node = new Node(data);
if (this.head == null) {
this.head = node;
this.tail = node;
return;
}
Node cur = this.head;
while (cur != tail) {
cur = cur.next;
}
this.tail.next = node;
node.prev = this.tail;
this.tail = node;
}
public boolean check(int index) {
if (index < 0 || index > size()) {
return true;
}
return false;
}
//任意位置插入,第一个数据节点为0号下标
public void addIndex(int index, int data) {
Node node = new Node(data);
if (check(index)) {
throw new RuntimeException("超过范围");
}
if (index == 0) {
addFirst(data);
} else if (index == size()) {
addLast(data);
} else {
Node cur = this.head;
while (index > 1) {
cur = cur.next;
index--;
}
cur.next.prev = node;
node.next = cur.next;
node.prev = cur;
cur.next = node;
}
}
//查找是否包含关键字key是否在单链表当中
public boolean contains(int key) {
Node cur = this.head;
while (cur != null) {
if (cur.data == key) {
return true;
}
cur = cur.next;
}
return false;
}
//删除第一次出现关键字为key的节点
public void remove(int key) {
Node cur = this.head;
if (contains(key)) {
if (this.head.data == key) {
this.head = this.head.next;
} else if (this.tail.data == key) {
this.tail = this.tail.prev;
this.tail.next = null;
} else if (this.head == this.tail) {
this.head = null;
} else {
while (cur != null) {
if (cur.data == key) {
cur.next.prev = cur.prev;
cur.prev.next = cur.next;
}
cur = cur.next;
}
}
} else {
System.out.println("不存在key");
}
}
//删除所有值为key的节点
public void removeAllKey(int key) {
Node cur = this.head;
if (contains(key)) {
while (cur != null) {
if (this.head.data == key) {
this.head = this.head.next;
} else {
cur.next.prev=cur.prev;
cur.prev.next =cur.next;
}
cur = cur.next;
}
} else {
System.out.println("不存在");
}
}
//得到单链表的长度
public int size() {
Node cur = this.head;
int cnt = 0;
while (cur != null) {
cur = cur.next;
cnt++;
}
return cnt;
}
public void display() {
Node cur = this.head;
while (cur != null) {
System.out.print(cur.data);
cur = cur.next;
}
System.out.println();
}
public void clear() {
while (this.head!=null){
Node cur=this.head.next;
this.head.next=null;
this.head.prev=null;
this.head=cur;
}
}
}
下面是main方法,写了一些对双链表的操作:
public class Test {
public static void main(String[] args) {
Node node = new Node();
//利用循环调用头插法,把数据插入到链表中
for (int i = 0; i < 5; i++) {
node.addFirst(i);
}
node.display();//打印双链表
System.out.println(node.size());//打印链表大小
node.addIndex(2, 7);//2位置插入7
node.addIndex(2, 7);//2位置插入7
node.display();//打印双链表
System.out.println(node.contains(0));//判断是否包含0;
//remove是移除出现的第一个元素
node.remove(4);
node.remove(2);
node.remove(1);
node.remove(0);
node.remove(3);
node.remove(7);
//因为元素都被移除了,再加一些元素进去
node.addFirst(7);
node.addFirst(7);
node.addFirst(7);
node.display();
node.removeAllKey(7);
node.display();
for (int i = 0; i < 5; i++) {
node.addFirst(i);
}
node.display();
node.clear();//清空链表
node.display();
}
}