数据结构—链表(总结)

链表

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到他们相交的距离相等,此时同时遍历两个链表
 *       直到遇到相同的节点为止,这个节点就是他们相交的节点。
 *       需要注意,在找相交点之前,需要先判断两个链表是否相交,相交再去找相交点。
 * */









  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值