不带头结点的单链表java实现
- 分析:
我们先说带头结点的单链表,带头结点的单链表在初始化时产生一个head结点,其data域和next域均为空。对带头结点的单链表进行操作分为头部操作和尾部操作。
1.头部操作:
**插入:**new一个新结点,将其插入到head结点之后,并移动后面结点(注意:不要“断链”)
删除:**new一个新节点指向head,将之后一个的结点置空即可(注意 :不要“断链”)
2.尾部操作
**插入:**new一个新结点,将其插到最后一个结点之后即可。
**删除:**找到最后一个结点的前一个结点(我用的是.getNext().getNext()!=null),将其next域置空即可
再来看不带头结点,不带头结点的单链表,实际上初始化时,产生了一个node结点,其next域和data域为空,不同点在于它已经不是头结点而是普通结点(即这个结点是第一个带值结点,而前面说的head结点是不带值的),所以在增加结点时,要判断这个结点是否是第一个结点且是否为空,若空则将值赋给这个结点否则申请新节点,尾插法。
即然没有头结点,那对链表的增加和删除结点操作只能使用尾删法和尾插法。
- 代码实现如下
class Entry<T>{
private T value;//数据域
private Entry<T> next;//next域
public Entry(T value){ this.value=value; }
public Entry(){/*申请头结点*/}
public T getValue() { return value; }
public void setValue(T value) { this.value = value; }
public Entry<T> getNext() { return next; }
public void setNext(Entry<T> next) { this.next = next; }
}
类Entry封装结点属性和操作:value域(data域) next域[1].
public class MyLinklist <E extends Comparable<E>> {
private Entry<E> node;
public MyLinklist(){
node=new Entry<>();
}
public MyLinklist(Entry<E> node) {
this.node = node;
}
/*尾插法*/
public void addTail(E value){
if(node.getValue()==null){
node.setValue(value);
}
else{
Entry<E>p=new Entry<>();
p=node;//设置一个新节点,将此节点指向插入前链表的最后一个结点
while(p.getNext()!=null){
p=p.getNext();
}
Entry newEntrty=new Entry(value);
p.setNext(newEntrty);
}
}
/*尾删法*/
public void deleteTail(){
Entry<E>p=new Entry<>();
p=node;//设置一个新节点,将此节点指向插入前链表的最后一个结点
while(p.getNext()==null)
p.setValue(null);
while(p.getNext().getNext()!=null){
p=p.getNext();
}
p.setNext(null);
}
/*按结点值查找 找到则返回true 否则false*/
public boolean searchNode(E vlaue){
Entry<E>p=new Entry<>();
p=node;
while(p!=null){
if(p.getValue()==vlaue)
return true;
p=p.getNext();
}
return false;
}
public boolean changeNode(E vlaue,E tochange){
Entry<E>p=new Entry<>();
p=node;
while(p!=null){
if(p.getValue()==vlaue) {
p.setValue(tochange);
return true;
}
p=p.getNext();
}
return false;
}
public void show(){//打印链表中每个结点值
Entry<E>p=new Entry<>();
p=node;
while(p!=null){
System.out.println(p.getValue());
p=p.getNext();
}
}
}
类MyLinklist封装单链表的属性和操作[1].
class TestDemo {
public static void main(String[] args) {
MyLinklist<Integer>my=new MyLinklist<>();
my.addTail(2);
my.addTail(3);
my.addTail(4);
my.addTail(5);
my.show();
System.out.println();
my.deleteTail();
my.deleteTail();
/* my.deleteTail();
my.deleteTail();*/
my.show();
System.out.println( "查找值为3的结点,结果为"+my.searchNode(3));
System.out.println("将值为2的结点的值改为5,结果为"+my.changeNode(2,5));
}
}
类TestDemo测试类,测试单链表的创建,删除/增加结点等[1].
**总结:**不带头结点的单链表与带头结点的相比较,不带头结点的只能在链表尾部进行插入/删除操作,这样头插法/头删法就无法实现,有一定的限制。记得在大一学的时候,老师也叮咛过不带头结点的单链表了解就好,主要还是要掌握带头结点的。带不带头,各有好处,根据情况而定。