带头节点 的单链表:在初始化时产生一个headEntry结点,其value域和next域均为空。其链表结构如下:
注意:带头节点和不带头节点的单链表区别就在headEntry
带头节点的单链表我们需要从headEntry的下个节点开始进行各种操作,而不带头节点的从headEntry开始操作,操作方法大同小异,适当分析,搞清楚起始点即可
- Entry类封装节点属性,包括value域及next域
- 代码实现如下:
public class Entry<E extends Comparable<E>> {
private E value;
private Entry next;
public Entry(){
}
public Entry(E value){
this.value=value;
}
public void setValue(E value) {
this.value = value;
}
public void setNext(Entry next) {
this.next = next;
}
public E getValue() {
return value;
}
public Entry getNext() {
return next;
}
}
- Link类封装头插尾插头删尾删等操作
- 代码实现如下:
package linklist;
//带头节点的单链表
public class Link<T extends Comparable<T>> {
private Entry<T> headEntry;
private Entry<T> tailEntry;
public Link(){
headEntry=new Entry<>();
}
//头插
public void addHead(T value){
Entry<T> newEntry=new Entry<>(value);
//头节点后无元素
if(headEntry.getNext()==null){
headEntry.setNext(newEntry);
tailEntry=newEntry;
}
newEntry.setNext(headEntry.getNext());
headEntry.setNext(newEntry);//更新头节点
if(headEntry.getNext().getNext()==null){
//头节点后只有一个元素时,需要更新尾节点
//头节点后存在多个元素时,不需要更新尾节点
tailEntry=newEntry;
}
}
//尾插
public void addTail(T value){
Entry<T> newEntry=new Entry<>(value);
//头节点后无元素
if(headEntry.getNext()==null){
headEntry.setNext(newEntry);
tailEntry=newEntry;
}
tailEntry.setNext(newEntry);
tailEntry=newEntry;//更新尾节点
}
//头删
public void deleteHead(){
if(headEntry.getNext()==null){//防止空指针异常
return;
}
Entry p=headEntry.getNext();
headEntry.setNext(headEntry.getNext().getNext());
p.setValue(null);//防止内存泄漏
p.setNext(null);
}
//尾删
public void deleteTail(){
if(headEntry.getNext()==null){
return;
}
Entry<T> p=headEntry.getNext();
for(;p.getNext().getNext()!=null;p=p.getNext()){
; //找尾部前驱p
}
p.getNext().setValue(null);//防止内存泄漏
p.setNext(null);
tailEntry=p;
}
public void deleteValue(T value){
//头节点后无元素
if(headEntry.getNext()==null){
return;
}
//若头节点后的第一个元素即为需要删除的元素,则相当于头删
if(headEntry.getNext().getValue().compareTo(value)==0){
deleteHead();
if(headEntry==tailEntry) {
tailEntry.setNext(null);//更新尾节点
}
return;
}
//若尾节点元素即为需要删除的元素,则相当于尾删
if(tailEntry.getValue().compareTo(value)==0){
deleteTail();
if(headEntry==tailEntry) {
tailEntry.setNext(null);
}
return;
}
//遍历链表,寻找指定删除元素
for(Entry<T> p = headEntry.getNext(); p.getNext().getNext()!=null; p=p.getNext()){
if(p.getNext().getValue().compareTo(value)==0){
p.getNext().setValue(null);
p.setNext(p.getNext().getNext());
break;
}
}
}