一.如何创建链表
使用静态内部类表示结点,Node实例对象.next表示下一个结点,用final修饰data,data只能被赋值一次。
二.链表添加元素
1.首部添加元素
首先创建新节点new,我们的目的是把new结点变为头结点,所以我们使new.next=head,
最后不要忘了把head更新,head=new。
2.中间添加元素
我们要使new结点插入node(15)和node(7)之间,我们就要在node(15)处停下,
使new.next=node(15).next,就相当于把node(15)指向node(7)的箭头连接到了new结点的尾巴上指到node(7),此时node(15).next是node(7)。
之后,使node(15).next=new,更新node(15)指向new。
3.尾部添加元素
我们只要将尾结点指向new结点即可
首先判断头结点是否为空以及插入位置pos是否合理,我们可以插入头部pos==1,插入尾部pos==size+1,以及插入1<pos<size+1的中间部分。
之后我们建立一个结点pNode=head,使pNode不断更新成为插入结点的前驱结点,这样就可以进行插入了。
三.链表删除元素
1.首部删除元素
更新head,head=head.next即可
2.中间删除元素
node(7)为删除目标结点,我们找到删除结点的前驱结点cur,
使cur.next=cur.next.next , cur.next是node(7),
简化为cur.next=node(7).next
3.尾部删除元素
我们找到删除结点的前驱结点即可,删除结点是node(50),前驱结点是node(7),我们可以使node(7).next=null,node(40)不可达,jvm就自动回收了。
首先判断头结点是否为空,以及删除位置pos是否合理,我们可以删除头结点pos==1,尾结点pos==size,以及其中间部分1<pos<size。
之后我们创建结点pNode指向head,使pNode不断更新为删除结点的前驱结点,之后就可以进行结点删除了。
四.双向链表如何构造及插入删除
单向链表是从前往后遍历,如果我们要操作的结点在链表靠后的位置,这样使用单链表的效率就很低,而使用双向链表就可以很好地解决这个问题,双向链表与单向链表相比,双向链表不仅有后继节点,还有前驱结点,这样不仅存储了下一个结点,还存储了前一个结点。
1.双向链表如何构造
与单向链表相比,增加了一个前驱结点。
2.插入
开头
使新插入结点nodeInsert的下一个节点为原本的head结点,
head结点的前一个结点为nodeInsert结点,然后更新head并返回。
中间
插入的是中间结点,我们可以遍历链表,根据pos找到要插入位置的node,创建node结点的前驱结点preNode,nodeInsert和node进行双向绑定,preNode和nodeInsert之间进行双向绑定,于是nodeInsert就插入到preNode和node之间了。
尾部
定位要准确,如果node为空会发生空指针异常,所以我们取到要插入位置的前一个结点node,使node.next=nodeInsert即可,nodeInsert前为node,后为null,并返回。
3.删除
一样使用遍历单向链表根据pos找到node结点,node为要删除的结点,preNode为node的前驱结点,nextNode为node的后继结点。
preNode为null就是删除头结点,使head=head.next即可;
nextNode为null就是删除尾结点,使preNode.next=null即可,node不可达,node会被jvm自动回收。
其余情况就是删除中间结点,把node的前驱和后继全断了,使preNode与nextNode相互连上。