我们发现在解决单链表问题的时候发现在增加和删除的时候总是要单独考虑链表中头结点,再解决其他中间位置的结点,那我们可以引入一个虚拟的头结点,这样无论链表中有没有结点都是一样的解决方法。
画图来看一下引入虚拟头结点后链表的操作过程
插入
在头结点插入
我们发现引入虚拟头结点后在头部插入结点和在中间任意位置插入结点的操作都是一样的
删除任意结点
删除头结点
引入虚拟头结点后的删除操作也是一样的,不需要单独对头结点的操作进行考虑
代码实现操作过程
class Node{
int data;
Node next;
public Node(int data) {
this.data = data;
}
}
public class SingleLinkedListDummy {
private int size;
//虚拟头结点,将它的值设置为单链表不会存在的值
private Node dummyHead= new Node(-1);
/**
* 任意位置插
* @param index
* @param data
*/
public void addIndex(int index,int data){
if(index < 0 || index > size)
{
System.out.println("index illegal");
return;
}
//前驱结点从虚拟头结点开始
Node prev=dummyHead;
for (int i = 0; i < index; i++) {
prev=prev.next;
}
Node node=new Node(data);
node.next=prev.next;
prev.next=node;
size++;
}
/**
* 头插
* @param data
*/
public void addFirst(int data){
addIndex(0,data);
}
/**
* 尾插
* @param data
*/
public void addLast(int data){
addIndex(size,data);
}
/**
* 删除指定索引的节点
* @param index
*/
public void removeIndex(int index){
//判断index的合法性
if(index < 0 || index >size-1)
{
System.out.println("index illegal!");
return;
}
//前驱结点从虚拟头结点开始
Node prev = dummyHead;
for (int i = 0; i < index; i++) {
prev=prev.next;
}
Node node=prev.next;
prev.next=node.next;
node.next=null;
size--;
}
/**
* 删除所有的data结点
* @param data
*/
public void removeData(int data){
//前驱结点从虚拟头结点开始
Node prev= dummyHead;
//前驱结点的下一个一定不能为空
while(prev.next != null)
{
//如果连续几个结点都是待删除的节点就一直删除
//不需要将前驱结点向后移动
if(prev.next.data==data)
{
Node node=prev.next;
prev.next=node.next;
node.next=null;
size--;
}
//当下一个节点不是待删除结点的时候再将前驱结点向后移动
else
{
prev=prev.next;
}
}
}
@Override
public String toString() {
String ret="";
Node prev=dummyHead;
while(prev.next!=null)
{
ret+=prev.next.data+"->";
prev=prev.next;
}
ret+="NULL";
return ret;
}
public static void main(String[] args) {
SingleLinkedListDummy singleLinkedListDummy=new SingleLinkedListDummy();
singleLinkedListDummy.addFirst(5);
singleLinkedListDummy.addFirst(1);
singleLinkedListDummy.addLast(5);
singleLinkedListDummy.addLast(5);
singleLinkedListDummy.addFirst(2);
singleLinkedListDummy.addLast(3);
singleLinkedListDummy.addFirst(5);
singleLinkedListDummy.addLast(5);
singleLinkedListDummy.addLast(5);
singleLinkedListDummy.addLast(5);
singleLinkedListDummy.addIndex(0,7);
singleLinkedListDummy.addIndex(0,5);
singleLinkedListDummy.addIndex(0,5);
singleLinkedListDummy.addIndex(0,5);
singleLinkedListDummy.addLast(5);
System.out.println(singleLinkedListDummy);
singleLinkedListDummy.removeIndex(4);
System.out.println(singleLinkedListDummy);
singleLinkedListDummy.removeData(5);
System.out.println(singleLinkedListDummy);
}
}
运行结果