不带头双向链表的头插、尾插、指定位置插入
对于双向链表的插入操作,为了方便起见,可以在链表初始化的时候定义一个头head(指向第一个元素),一个尾巴last(指向最后一个元素)
1、头插
分析:
对于双向链表的头插,一般分为第一次插入和不是第一次插入。具体见下图:
程序如下:
public void addFirst(int data) {
Node node = new Node(data);
if (head==null){
this.head=node;
this.last=node;//第一次插入的时候的尾巴node
}else{
node.next=this.head;
this.head.prev=node;
this.head=node;
}
}
2、尾插
尾插也分为第一此插入和不是第一次插入,具体见下图
程序如下:
public void addLast(int data) {
Node node=new Node(data);
if (this.head==null){
this.head=node;
this.last=node;
}else{
this.last.next=node;//绑后继
node.prev=this.last;//绑前驱
this.last=node;//新的尾巴last移动
}
}
3、按指定位置插入
分析:对于指定位置插入,首先要对插入位置进行合法性判断,合法之后再找出index的位置的结点,找到之后将元素进行插入,如果index=1时,直接调用头插的方法;如果index=链表的长度,直接调用尾插的方法;剩下的就是普通插入,因为双向链表有前驱,也有后继,所以在改变前驱和后继的指向的时候就需要改变四个。
程序如下:
private Node searchIndex(int index){
if (index<0||index>getLength()){
throw new UnsupportedOperationException("下标不合法");
}
int count=0;
Node cur=this.head;
while(count!=index){
cur=cur.next;
count++;
}
return cur;
}
public boolean addIndex(int index, int data) {
//cur指向index位置的结点
Node cur=searchIndex(index);
Node node=new Node(data);
if (index==0){
addFirst(data);
return true;
}
if (index==getLength()){
addLast(data);
return true;
}
node.next=cur;
cur.prev.next=node;
node.prev=cur.prev;
cur.prev=node;
return true;
}
在此处用到了链表的长度getLength(),所以在此处链表的长度的小方法如下:
public int getLength() {
int count=0;
Node cur=this.head;
while(cur!=null){
count++;
cur=cur.next;
}
return count;
}