无头双向单链表的基础功能实现
在单链表的学习中,我们已经掌握了求单链表的长度,是否包含了某一个元素,以及打印单链表,无头双链表的求长度,判断是否包含了某一个元素,打印双链表,都是与单链表的写法一样的,所以这里就不在多做赘述。
头插法
变化前
变化后
代码实现:
//头插法 public void addFirst(int data){ listnode add=new listnode(data); if (head==null){//还得考虑链表为空的情况 head=add; last=add; return; } add.next=head; head.prve=add; head=add; }
尾插法
变化前
变化后
代码实现:
//尾插法 public void addLast(int data){ listnode add=new listnode(data); if (head==null){//同样需要考虑要是有空列表的情况 head=add; last=add; return; } last.next=add; add.prve=last; last=add; }
删除第一次出现关键字为key的节点
一般情况
出现在头部情况(假设要删除的第一次数据在头部出现):
出现在尾部(假设要删除的数据最后才第一次出现):
对以上情况进行分析之后,我们必须通过遍历来解决,具体实现代码如下:
//删除第一次出现关键字为key的节点 public void remove(int key){ if (head==null)return; listnode cur=head; while (cur!=null){ if (cur.val==key){ if (cur==head){ cur.next.prve=null; head=head.next; }else{ cur.prve.next=cur.next; if (cur==last){ last=cur.prve; }else{ cur.next.prve=cur.prve; } } return; }else{ cur=cur.next; } } }
但是在这里代码是有缺陷的,因为如果就是一个节点的时候,那么此时代码会报错,我们就需要单独讨论一下,具体代码实现如下:
public void remove(int key){ if (head==null)return; listnode cur=head; while (cur!=null){ if (cur.val==key){ if (cur==head){ head=head.next; if (head!=null){ head.prve=null; }else{ last=null;//尾节点要变成null,不然会被一直引用 } }else{ cur.prve.next=cur.next; if (cur==last){ last=cur.prve; }else{ cur.next.prve=cur.prve; } } }else{ cur=cur.next; } } }
删除所有的值为key的节点
这个就需要在删第一次为key的基础上,把return去掉,然后要让cur一直往下走,具体实现代码如下:
//删除所有值为key的节点 public void removeAllKey(int key){ if (head==null)return; listnode cur=head; while (cur!=null){ if (cur.val==key){ if (cur==head){ head=head.next; if (head!=null){ head.prve=null; }else{ last=null; } }else{ cur.prve.next=cur.next; if (cur.next!=null){ cur.next.prve=cur.prve; }else{ last=last.prve; } } } cur=cur.next; } }
任意位置插入
插入前:
插入后
代码实现如下:
//任意位置插入,第一个数据节点为0号下标 public listnode search(int index){ if (index<0||head==null)return null; listnode cur=head; while (index!=0){ cur=cur.next; if (cur==null){//说明超出链表的长度 return null; } index--; } return cur; } public void addIndex(int index,int data){ listnode listnode=new listnode(data); if (index==0){//如果是第一个位置就是头插法 addFirst(data); return; } if (index==size()){//最后一个位置就是尾插法 addLast(data); return; } listnode ret=search(index); if (ret==null)return; ret.prve.next=listnode; listnode.next=ret; listnode.prve=ret.prve; ret.prve=listnode; }
清空双链表
代码实现:
public void clear(){ while(head!=null){ listnode cur=head.next; head.prve=null; head.next=null; head=cur; } last=null;//要把尾节点手动置为null,不然还在被引用 }