无头双向链表
在Java的集合框架库中LinkedList底层实现就是无头双向循环链表。
无头双向循环链表实现
链表的功能实现代码
class Node {
public int data;//保存数据
public Node next;
public Node prev;
public Node (int data){
this.data = data;
}
}
public class MyLinkedList {
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;
} else {//不是第一次插入
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;
} else {
this.tail.next = node;
node.prev = this.tail;
this.tail = this.tail.next;
}
}
private void checkIndex(int index){//判断插入的index位置的合法性
if (index < 0 || index > size()){
throw new RuntimeException("index不合法");
}
}
private Node searchIndex(int index){//搜索插入的位置
Node cur = this.head;
while (index != 0){
cur = cur.next;
index--;
}
return cur;
}
public void addIntex(int index,int data){//任意位置插入,第一个数据节点为0号下标
/*1:判断index的合法性
* 2:判断是否是第一次插入,如果是,则用头插法
* 3:如果不是第一次插入,再判断是不是插入到最后位置,如果是则用尾插法
* 4:中间位置插入考虑4个位置*/
checkIndex(index);
if (index == 0){//直接用头插法就好了
addFirst(data);
return ;
}
if (index == size()){//直接用尾插法就好
addLast(data);
return ;
}
Node cur = searchIndex(index);
Node node = new Node(data);//可以画图考虑这四个位置
node.next = cur;
node.prev = cur.prev;
cur.prev.next = node;
cur.prev = node;
}
public boolean contains(int key){//查找是否包含关键字key
Node cur = this.head;
while(cur != null){
if (cur.data == key){
return true;
}
cur = cur.next;
}
return false;
}
public int remove(int key){//删除第一次出现关键字为key的节点
Node cur = this.head;
while (cur != null){
if (cur.data == key){
int oldData = cur.data;
if (cur == this.head){//删除头结点的情况
this.head = this.head.next;
this.head.prev = null;
} else {
cur.prev.next = cur.next;
if (cur.next != null){
cur.next.prev = cur.prev;
} else {
//删除的是尾巴节点,只需要移动tail
this.tail = cur.prev;
}
}
return oldData;
}
cur = cur.next;
}
return -1;
}
public void removeAllKey(int key){//删除所有值为key的节点
Node cur = this.head;
while (cur != null){
if (cur.data == key){
int oldData = cur.data;
if (cur == this.head){//删除头结点的情况
this.head = this.head.next;
if (this.head != null) {
this.head.prev = null;
}
} else {
cur.prev.next = cur.next;
if (cur.next != null){
cur.next.prev = cur.prev;
} else {
//删除的是尾巴节点,只需要移动tail
this.tail = cur.prev;
}
}
}
cur = cur.next;
}
}
public int size(){//得到单链表的长度
int count = 0;
Node cur = this.head;//定义一个cur节点
while (cur != null){
count++;
cur = cur.next;
}
return count;
}
public void display(){//打印双向链表
Node cur = this.head;
while (cur != null){
System.out.println(cur.data+" ");
cur = cur.next;
}
}
/*需要一个一个节点进行释放*/
public void clear(){//清除链表
while (this.head != null){
Node cur = this.head.next;
this.head.prev = null;
this.head.next = null;
this.head = cur;
}
this.tail = null;
}
}
测试部分代码
public class TestDemo {
public static void main(String[] args) {
MyLinkedList myLinkedList = new MyLinkedList();
myLinkedList.addLast(5);
myLinkedList.addLast(5);
myLinkedList.addLast(5);
myLinkedList.addLast(5);
myLinkedList.addLast(5);
myLinkedList.addLast(5);
myLinkedList.addLast(5);
//myLinkedList.display();
/* System.out.println(myLinkedList.contains(4));
System.out.println(myLinkedList.size());*/
// myLinkedList.addIntex(5,100);
// myLinkedList.display();
myLinkedList.clear();
}
}