链表
1.增
在链表中插入一个目标节点keyNode
(1)在链表尾插入:直接找到最后一个节点lastNode,使得lastNode.next=keyNode
(2)在链表中间插入,特别是插入节点后要保持链表的有序性的问题:需要找到插入的位置,比如要查到mNode和nNode之间,那么:
mNode.next=keyNode , keyNode.next=nNode
2.删
在链表中删除一个目标节点keyNode
(1)在链表末尾删除一个node,
如果知道头结点(head),通过遍历找到倒数第二个节点node1,使得node1.next=null;
如果不知道头结点,那么末尾节点是无法删除的。
(2)删除中间节点node,
如果直到头结点(head),通过两个指针pre=head,curr=head.next,同时移动pre和curr(pre=pre.next,curr=curr.next),当curr为要被删除的目标节点时,pre.next=curr.next,即可将curr删除;
如果不知道头结点,int temp=node.val; node.val=node.next.val; node.next.val=temp; node.next=node.next.next ...即可
3.排序
Node tmp=head;
两层循环:外循环遍历从第一个节点至倒数第二个节点,循环条件:while(tmp.next!=null)
内循环遍历从外循环的当前元素的下一个节点(Node next=tmp.next)开始,至最后一个节点。循环条件:while(next!=null)
主要思想就是通过n-1轮遍历,每一轮都是把最小(最大)元素放在合适的位置。比如升序,第一轮是把最小元素放在第一个位置。然后给第二个位置找合适的元素。外循环更像是给某个位置找合适的元素。
4.删除链表中的重复数据
思路1:遍历链表,使用集合,将没有放入集合中的遍历到的元素放在集合中。当再次遍历到相同元素时,直接删除。
思路2:双重循环,外循环从头至尾遍历元素,内循环从外循环的当前元素的下一元素开始遍历,遍历至末尾,发现与外循环当前元素相同的元素删除。
5.删除单链表中的倒数第k个元素
思路1:删除倒数第k个,就是删除正数第len-k个。这个需要两次遍历,第一次获取链表长度,第二次遍历到len-k个元素;
思路2:定义两个指针,两个指针相差k-1,并往后同时移动,当后一个指针到达链表尾时,前一个指针正好在倒数第k个位置。
6.链表反转
假设有i,m,n三个节点。i->m->n * 那么在反转的过程中就是把指针箭头反转。 * 如果将m->i,那么就没有指针指向n了,链表就断开了,所以,在反转的过程中需要在调整m的next之前,需要把n保存下来。
public static void reverseIteratively(){ Node pReversedHead=head; Node pNode=head; Node pPrev=null; while(pNode!=null){ Node pNext=pNode.next; if(pNext==null) pReversedHead=pNode; pNode.next=pPrev; pPrev=pNode; pNode=pNext; } head=pReversedHead; }
7.逆序输出链表节点
public static void printListReversely(Node head){ if(head!=null){ printListReversely(head.next); System.out.println(head.val); } }
8.寻找单链表的中间节点
思路:还是需要指定两个指针:fast=head; slow=head;
fast每次走两步:fast=fast.next.next
slow每次走一步:slow=slow.next
当fast走到末尾节点的时候,slow正处于中间节点的位置
需要注意的是:如果链表长度为奇数,那么中间节点就是slow指向的节点;如果链表长度为偶数,那么中间节点就是slow指向的节点和slow的下一个节点。
9.检测链表是否有环
思路:还是需要指定两个指针:fast=head; slow=head;
fast每次走两步:fast=fast.next.next
slow每次走一步:slow=slow.next
两个指针每移动一次都需要比较是否相等,如果快指针等于慢指针,则证明这个链表是带环的单向链表,否则,证明这个链表是不带环的循环链表(fast先行到达尾部为NULL,则为无环链表)。10.判断两个链表是否相交
思路:如果两个链表相交,则必然有相同的尾节点,如果他们的尾节点相同,那么这两个链表相交,否则不相交。
11.如何找到相交链表的相交节点
/** * 如果两个链表相交,如何找到他们相交的第一个节点呢 * 思路:首先分别计算两个链表的长度len1,len2(假设了len1>len2), * 接着先对链表head1遍历(len1-len2)个节点到节点p,此时节点p与head2到他们相交的距离相等,此时同时遍历两个链表 * 直到遇到相同的节点为止,这个节点就是他们相交的节点。 * 需要注意,在找相交点之前,需要先判断两个链表是否相交,相交再去找相交点。 * */