无头双向链表:在Java的集合框架库中LinkedList底层实现就是无头双向循环链表
总结:
单向链表在删除一个节点的时候,需要借助前驱节点,才能删除。
双向链表删除节点,不需要借助前驱节点
因为双向链表,它存储前驱和后驱的节点的地址,它都知道。
另外双向链表会多一个引用last,这个引用永远指向此时链表的尾巴节点
head就是永远指向双向链表的头节点。
class ListNode{
//存储int类型的数据
public int val;
//存储上一个节点的地址
public ListNode prev;
//存储下一个节点的地址
public ListNode next;
public ListNode(int val){
//构造方法
this.val = val;
}
}
public class MyLinkedList {
//指向双向链表的头结点
public ListNode head;
//指向双向链表的尾巴节点
public ListNode last;
//头插法
public void addFirst(int data){
};
//尾插法
public void addLast(int data){
};
//任意位置插入,第一个数据节点为0号下标
public boolean addIndex(int index,int data){
return true;
};
//查找是否包含关键字key是否在单链表当中
public boolean contains(int key){
return true;
};
//删除第一次出现关键字为key的节点
public void remove(int key){
};
//删除所有值为key的节点
public void removeAllKey(int key){
};
//得到单链表的长度
public int size(){
return 0;
};
public void display(){
};
public void clear(){
};
}
实现LinkedList中的所有方法
通过这些方法就可以操作链表
//打印链表
public void display(){
ListNode cur = this.head;
while(cur != null){
System.out.print(cur.val + " ");
cur = cur.next;
}
System.out.println();
};
//得到链表的长度
public int size(){
ListNode cur = this.head;
int count = 0;
while(cur != null){
count++;
cur = cur.next;
}
return count;
};
//查找是否包含关键字key是否在单链表当中
//找到返回true,找不到返回false
public boolean contains(int key){
ListNode cur = this.head;
while (cur != null){
if(cur.val == key){
return true;
}
cur = cur.next;
}
return false;
};
//头插法
public void addFirst(int data){
ListNode node = new ListNode(data);
if(this.head == null){
this.head = node;
this.last = node;
}else {
node.prev = this.head.prev;
node.next = head;
head = node;
}
};
//尾插法
public void addLast(int data){
ListNode node = new ListNode(data);
if(this.head == null){
this.head = node;
this.last = node;
} else {
this.last.next = node;
node.prev = this.last;
last = node;
//任意位置插入,第一个数据节点为0号下标
//任意位置插入,第一个数据节点为0号下标
public void addIndex(int index,int data){
ListNode node = new ListNode(data);
//当链表为空的时候
if(this.head == null){
addFirst(data);
return;
}
//当链表不为空的时候,
if(index == 0){
addFirst(data);
return;
}
if (index == size()){
addLast(data);
return;
}
ListNode cur = this.head;
while(index-1 != 0){
cur = cur.next;
index--;
}
node.prev = cur;
node.next = cur.next;
cur.next = node;
node.prev = cur.next.prev;
};
//删除第一次出现关键字为key的节点
public void remove(int key){
ListNode cur = this.head;
if(this.head == null){
System.out.println("链表为空");
return;
}
//如果删除的是头结点
if(this.head.val == key){
this.head = this.head.next;
this.head.prev = null;
return;
}
//如果删除的是尾巴结点
if(this.last.val == key){
this.last = this.last.prev;
this.last.next = null;
return;
}
//删除的是中间的节点
while (cur != null){
if(cur.val == key){
cur.prev.next = cur.next;
cur.next.prev = cur.prev;
return ;
}
cur = cur.next;
}
};
//删除所有值为key的节点
public void removeAllKey(int key){
if(this.head == null){
System.out.println("链表为空!");
return;
}
ListNode cur = this.head;
while(cur != null){
if(cur.val == key){
if(cur == this.head){
//如果key值是头结点
this.head = this.head.next;
if(head != null){
//不止一个节点
this.head.prev = null;
}else {
//如果只有一个节点,并且也是要删除的节点
this.last = null;
}
}else {
cur.prev.next = cur.next;
//不是头结点
if(cur.next != null){
cur.next.prev = cur.prev;
}else {
this.last = this.last.prev;
}
}
}
cur = cur.next;
}
};
public void clear(){
if(this.head == null){
System.out.println("链表为空!");
return;
}
while (this.head != null){
ListNode headNext = this.head.next;
this.head.prev =null;
this.head.next = null;
this.head = headNext;// head 在此过程中,置为null,因为 最后一个元素的next 等null,
}
this.last = null;
};
class ListNode{
//存储int类型的数据
public int val;
//存储上一个节点的地址
public ListNode prev;
//存储下一个节点的地址
public ListNode next;
public ListNode(int val){
//构造方法
this.val = val;
}
}
public class MyLinkedList {
//指向双向链表的头结点
public ListNode head;
//指向双向链表的尾巴节点
public ListNode last;
//得到链表的长度
public int size(){
ListNode cur = this.head;
int count = 0;
while(cur != null){
count++;
cur = cur.next;
}
return count;
};
//打印链表
public void display(){
ListNode cur = this.head;
while(cur != null){
System.out.print(cur.val + " ");
cur = cur.next;
}
System.out.println();
};
//头插法
public void addFirst(int data){
ListNode node = new ListNode(data);
if(this.head == null){
this.head = node;
this.last = node;
}else {
node.prev = this.head.prev;
node.next = head;
this.head = node;
}
};
//尾插法
public void addLast(int data){
ListNode node = new ListNode(data);
if(this.head == null){
this.head = node;
this.last = node;
} else {
this.last.next = node;
node.prev = this.last;
last = node;
}
};
//任意位置插入,第一个数据节点为0号下标
public void addIndex(int index,int data){
ListNode node = new ListNode(data);
//当链表为空的时候
if(this.head == null){
addFirst(data);
return;
}
//当链表不为空的时候,
if(index == 0){
addFirst(data);
return;
}
if (index == size()){
addLast(data);
return;
}
ListNode cur = this.head;
while(index-1 != 0){
cur = cur.next;
index--;
}
node.prev = cur;
node.next = cur.next;
cur.next = node;
node.prev = cur.next.prev;
};
//查找是否包含关键字key是否在单链表当中
public boolean contains(int key){
ListNode cur = this.head;
while (cur != null){
if(cur.val == key){
return true;
}
cur = cur.next;
}
return false;
};
//删除第一次出现关键字为key的节点
public void remove(int key){
ListNode cur = this.head;
if(this.head == null){
System.out.println("链表为空");
return;
}
//如果删除的是头结点
if(this.head.val == key){
this.head = this.head.next;
//this.head.prev = null;
return;
}
//如果删除的是尾巴结点
if(this.last.val == key){
this.last = this.last.prev;
this.last.next = null;
return;
}
//删除的是中间的节点
while (cur != null){
if(cur.val == key){
cur.prev.next = cur.next;
cur.next.prev = cur.prev;
return;
}
cur = cur.next;
}
};
//删除所有值为key的节点
public void removeAllKey(int key){
if(this.head == null){
System.out.println("链表为空!");
return;
}
ListNode cur = this.head;
while(cur != null){
if(cur.val == key){
if(cur == this.head){
//如果key值是头结点
this.head = this.head.next;
if(head != null){
//不止一个节点
this.head.prev = null;
}else {
//如果只有一个节点,并且也是要删除的节点
this.last = null;
}
}else {
cur.prev.next = cur.next;
//不是头结点
if(cur.next != null){
cur.next.prev = cur.prev;
}else {
this.last = this.last.prev;
}
}
}
cur = cur.next;
}
};
public void clear(){
if(this.head == null){
System.out.println("链表为空!");
return;
}
while (this.head != null){
ListNode headNext = this.head.next;
this.head.prev =null;
this.head.next = null;
this.head = headNext;// head 在此过程中,置为null,因为 最后一个元素的next 等null,
}
this.last = null;
};
}
组织数据上:
操作数据上: