LinkedList链表知识点概括(一)

作者:爱塔居的博客_CSDN博客-JavaSE,数据结构领域博主

专栏:数据结构

作者简介:大三学生,希望2023年迎来更优秀的自己!希望跟大家一同进步~

LinkedList链表知识点概括(一)_第1张图片

文章目录

前言

一、链表的基本概念

二、面试题实战


前言

顺序表/ArrayList:

优点:当给定下标的时候,查找速度非常快,适合给定下表的查找,时间复杂度为O(1);

缺点:插入必须要挪动元素,然后才能插入;删除必须挪动元素,才能删除。另外每次扩容也是浪费资源的。因为扩容的时候是1.5倍扩容。比如已经有10个元素了,要放第11个元素,就要扩容到15个,但只有11个元素,就有4个是浪费的。

ArrayList不适合做任意位置的插入和删除比较多的场景。

为了解决这些问题,我们可以使用链式存储:链表。

例题:关于链表和顺序表间的区别,叙述错误的是(D    )

A.链表和顺序表都属于线性表

B.链表不能随机访问其中的某个元素,顺序表可以

C.链表能做的事,顺序表都可以完成,只是操作方法不同,效率不同

D.链表在进行插入和删除的时候,速度总是比顺序表快

解析:链表的插入和删除不是所有情况下都比顺序表快,比如尾插尾删,顺序表的时间复杂度为O(1),并且如果是单链表,如果要在中间某个节点的前面插入/删除一个节点,则需要遍历。所以时间的快慢要分情况看待。

线性表(linear list)是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使用的数据结构,常见的线性表:顺序表、链表、栈、队列...
 


 

一、链表的基本概念

链表是一种物理存储结构上非连续存储结构,数据元素的逻辑顺序是通过链表中的引用链接次序实现的 ,就像火车,一节节的车厢可以看作是节点(结点)。

LinkedList链表知识点概括(一)_第2张图片

val:存储数据

next:存储下一个节点的地址(作用是连接当前节点和下一个节点)

LinkedList链表知识点概括(一)_第3张图片

 注意:

1.链表在逻辑上是连续的,但是在物理上不一定连续。顺序表在物理上一定是连续的,逻辑上是连续的。

2.现实中的结点一般都是从堆上申请出来的。

3.从堆上申请的空间,是按照一定的策略来分配的,两次申请的空间可能连续,也可能不连续。


链式结构分类:通过单\双向、带头\不带头、循环\非循环分为8类

1、单向 带头 循环

LinkedList链表知识点概括(一)_第4张图片

2、单向 带头 非循环

LinkedList链表知识点概括(一)_第5张图片 单向带头非循环

3、单向 不带头 循环

4、单向 不带头 非循环

LinkedList链表知识点概括(一)_第6张图片 单向不带头非循环

5、双向 带头 循环

6、双向 带头 非循环

7、双向 不带头 循环

8、双向 不带头 非循环

LinkedList链表知识点概括(一)_第7张图片 双向不带头非循环

虽然有八种类型,但是我们只学习单向不带头非循环双向不带头非循环两种类型。

因为笔试面试都是单向不带头非循环结构。而结合类底层是按双向不带头非循环操作的。

链表代码链接

二、面试题实战

1. 删除链表中等于给定值 val 的所有节点。
力扣

class Solution {
    public ListNode removeElements(ListNode head, int val) {
    //一个结点也没有
    if(head==null){
        return null;
    }
    ListNode cur=head;//new一个节点,从头节点开始
    ListNode pre=head.next;//new一个节点,比cur先走一步
    while(pre!=null){
        //当cur节点的值等于val时,要跳过这个节点
        if(pre.val==val){
         //
         cur.next=pre.next;
         pre=pre.next;
        }else{
            //不等于,就继续
            cur=pre;
            pre=pre.next;
        }
    }
    //当头节点的值等于val时,直接头节点后挪
    if(head.val==val){
        head=head.next;
    }
    return head;
     }
    }

LinkedList链表知识点概括(一)_第8张图片

2. 反转一个单链表

力扣

class Solution {
    public ListNode reverseList(ListNode head) {
    //链表没有节点
     if(head==null){
         return null;
     }
     //链表只有一个节点,反转后还是一样的
     if(head.next==null){
         return head;
     }
     ListNode cur=head.next;
     head.next=null;//将头节点跟第二个节点断开。
     //进行头插法
     while(cur!=null){
       ListNode curNext=cur.next;
       cur.next=head;
       head=cur;
       cur=curNext;
     }
     return head;
    }
}

LinkedList链表知识点概括(一)_第9张图片


3.给定一个带有头结点 head 的非空单链表,返回链表的中间结点。如果有两个中间结点,则返回第二个中间结点。

力扣
 

class Solution {
    public ListNode middleNode(ListNode head) {
    //利用快慢指针来做
    //new两个新的节点从头节点开始出发,fast每次走两步,slow每次走一步
    //如果链表节点为偶数,正好fast.next==null时,slow走到中点。如果是奇数,fast==null时,slow走到中点。
     ListNode fast=head;
     ListNode slow=head;
     while(fast!=null&&fast.next!=null){
         fast=fast.next.next;//走两步
         slow=slow.next;//走一步
     }
     return slow;
    }
}

LinkedList链表知识点概括(一)_第10张图片

 4. 输入一个链表,输出该链表中倒数第k个结点。

链表中倒数第k个结点_牛客题霸_牛客网

public class Solution {
    public ListNode FindKthToTail(ListNode head,int k) {
        if(k<=0||head==null){
            return null;
        }
        ListNode fast=head;
        ListNode slow=head;
        //依旧是使用快慢指针的方法
        //先new两个节点从头节点开始,fast先向前走k-1步
        //然后fast和slow每次同时走一步,当fast到终点的时候,slow正好在倒数第k个节点上。
        //当fast.next==null时,正好到终点
        while(k-1!=0){
            fast=fast.next;
            if(fast==null){
                return null;
            }
            k--;
        }
        while(fast.next!=null){
            fast=fast.next;
            slow=slow.next;
        }
        return slow;
    }
}

LinkedList链表知识点概括(一)_第11张图片

5. 将两个有序链表合并为一个新的有序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
 力扣

class Solution {
    public ListNode mergeTwoLists(ListNode head1, ListNode head2) {
    ListNode newhead=new ListNode(0);//新new一个虚拟链表
    ListNode temp=newhead;//temp指向链表的头节点
    while(head1!=null && head2!=null){
       if(head1.val>head2.val){//哪个链表的头节点值小,就连哪一个节点
           temp.next=head2;
           head2=head2.next;
           temp=temp.next;
       }else{
           temp.next=head1;
           head1=head1.next;
           temp=temp.next;
       }
    }
    //最后一个节点
    if(head1!=null){
        temp.next=head1;
        
    }
    if(head2!=null){
        temp.next=head2;
    }
    return newhead.next;
    }
}

LinkedList链表知识点概括(一)_第12张图片

你可能感兴趣的:(数据结构,数据结构,java)