链表的顶级理解

目录

1.链表的概念及结构

2.链表的分类

单向或者双向

带头或者不带头

循环或者非循环

3.无头单向非循环链表的实现

3.1创建单链表

3.2遍历链表

3.3得到单链表的长度

3.4查找是否包含关键字

3.5头插法

3.6尾插法

3.7任意位置插入

3.8删除第一次出现关键字为key的节点

3.9回收链表

3.10完整代码


1.链表的概念及结构

概念:

链表是一种 物理存储结构上非连续 存储结构,数据元素的 逻辑顺序 是通过链表中的 引用链接 次序实现的 。

结构:

实际在内存中每个节点的地址是随机的,只不过用这个节点的next,找到了下一个节点的地址,实现链接。


2.链表的分类

实际中链表的结构非常多样

以下情况组合起来就有8种链表结构:

单向或者双向

带头或者不带头

循环或者非循环

++我们重点掌握无头单向非循环链表, 这种结构在笔试面试中出现很多。并且可以触类旁通其他结构。++


3.无头单向非循环链表的实现

链表的功能与顺序表类似,无非是增删查改,在某位置的插入与删除,对数据内容进行管理和操作。

具体实现内容:
(1)创建单链表
(2)遍历链表
(3)得到单链表的长度
(4)查找是否包含关键字
(5)头插法
(6)尾插法
(7)任意位置插入
(8)删除第一次出现关键字为key的节点
(9)回收链表

3.1创建单链表

java 复制代码
public class MyLinkedList {
    class Node {
        public int val;
        public Node next;

        public Node(int val) {
            this.val = val;
        }
    }
    public Node head;// 代表当前链表的头节点的引用
}

3.2遍历链表

java 复制代码
public void disPlay() {
        Node sur = head;
        while(sur  != null) {
            System.out.print(sur.val+" ");
            sur = sur.next;
        }
    }

3.3得到单链表的长度

进行遍历,并进行记录,最后进行返回就行

java 复制代码
public int size(){
        int count = 0;
        Node cur = head;
        while (cur != null) {
            count++;
            cur = cur.next;
        }
        return count;
    }

3.4查找是否包含关键字

对链表进行遍历,然后一一比

java 复制代码
 //查找是否包含关键字key是否在单链表当中
    public boolean contains(int key){
        Node cur = head;
        while (cur != null) {
            if(cur.val == key) {
                return true;
            }
            cur = cur.next;
        }
        return false;
    }

3.5头插法

将第一个节点的地址赋给我们新添加的节点的next,并且将新添加的节点赋给head,作为新的头节点

java 复制代码
  public void addFirst(int data){
        Node node = new Node(data);
        node.next = head;
        head = node;
    }

3.6尾插法

首先对该链表进行遍历,当遍历到最后一个节点时,将新添加的节点的地址最后一个节点的next。

如果该链表为空,直接将该新增节点设为头节点

java 复制代码
 public void addLast(int data){
        Node node = new Node(data);
        if(head == null) {
            head = node;
            return;
        }
        Node cur = head;
        while (cur.next != null) {
            cur = cur.next;
        }
        cur.next = node;
    }

3.7任意位置插入

需要插入的位置必须为合法,如果不合法,我们会抛出一个异常进行提醒

java 复制代码
public class ListIndexOutOfException extends RuntimeException{
    public ListIndexOutOfException() {
    }

    public ListIndexOutOfException(String message) {
        super(message);
    }
}

任意位置插入,我们可以分为种情况,插在开头,插在结尾,插在中间

插在结尾和插在中间可以总结成一种

java 复制代码
    //任意位置插入,第一个数据节点为0号下标
    public void addIndex(int index,int data)
            throws ListIndexOutOfException{
        checkIndex(index);
        if(index == 0) {
            addFirst(data);
            return;
        }
       
        Node cur = findIndexSubOne(index);
        Node node = new Node(data);
        node.next = cur.next;
        cur.next = node;
    }

    /**
     * 找到 index-1位置的节点的地址
     * @param index
     * @return
     */
    private Node findIndexSubOne(int index) {
        Node cur = head;
        int count = 0;
        while (count != index-1) {
            cur = cur.next;
            count++;
        }
        return cur;
    }
    private void checkIndex(int index) throws ListIndexOutOfException{
        if(index < 0 || index > size()) {
            throw new ListIndexOutOfException("index位置不合法");
        }
    }

3.8删除第一次出现关键字为key的节点

分为四种情况

(1)一个节点都没有

(2)删除数据在第一个

(3)没有你要删除的数据

(4)有你要删除的数据且不是第一个

java 复制代码
//删除第一次出现关键字为key的节点 O(N)
    public void remove(int key)throws ListIndexOutOfException{
        checkIndex(key);
        if(head == null) {
            return ;//一个节点都没有
        }
        //删除数据在第一个
        if(head.val == key) {
            head = head.next;
            return;
        }
        Node cur = searchPrev(key);
         //没有你要删除的数据
        if(cur == null) {
            return;
        }
        Node del = cur.next;//要删除的节点
        cur.next = del.next;
    }

    /**
     * 找到关键字key的前一个节点
     * @param key
     * @return
     */
    private Node searchPrev(int key) {
        Node cur = head;
        while (cur.next != null) {
            if(cur.next.val == key) {
                return cur;
            }
            cur = cur.next;
        }
        return null;//没有你要删除的节点
    }

3.9回收链表

将头节点置为空

java 复制代码
public void clear() {
        head = null;
    }

3.10完整代码

java 复制代码
public class MyLinkedList {
    class Node {
        public int val;
        public Node next;

        public Node(int val) {
            this.val = val;
        }
    }
    public Node head;// 代表当前链表的头节点的引用
    public void disPlay() {
        Node sur = head;
        while(sur  != null) {
            System.out.print(sur.val+" ");
            sur = sur.next;
        }
    }
    public int size(){
        int count = 0;
        Node cur = head;
        while (cur != null) {
            count++;
            cur = cur.next;
        }
        return count;
    }

    //查找是否包含关键字key是否在单链表当中
    public boolean contains(int key){
        Node cur = head;
        while (cur != null) {
            if(cur.val == key) {
                return true;
            }
            cur = cur.next;
        }
        return false;
    }
    public void addFirst(int data){
        Node node = new Node(data);
        node.next = head;
        head = node;
    }
    public void addLast(int data){
        Node node = new Node(data);
        if(head == null) {
            head = node;
            return;
        }
        Node cur = head;
        while (cur.next != null) {
            cur = cur.next;
        }
        cur.next = node;
    }
    //任意位置插入,第一个数据节点为0号下标
    public void addIndex(int index,int data)
            throws ListIndexOutOfException{
        checkIndex(index);
        if(index == 0) {
            addFirst(data);
            return;
        }

        Node cur = findIndexSubOne(index);
        Node node = new Node(data);
        node.next = cur.next;
        cur.next = node;
    }

    /**
     * 找到 index-1位置的节点的地址
     * @param index
     * @return
     */
    private Node findIndexSubOne(int index) {
        Node cur = head;
        int count = 0;
        while (count != index-1) {
            cur = cur.next;
            count++;
        }
        return cur;
    }
    private void checkIndex(int index) throws ListIndexOutOfException{
        if(index < 0 || index > size()) {
            throw new ListIndexOutOfException("index位置不合法");
        }
    }



    //删除第一次出现关键字为key的节点 O(N)
    public void remove(int key)throws ListIndexOutOfException{
        checkIndex(key);
        if(head == null) {
            return ;//一个节点都没有
        }
        //删除数据在第一个
        if(head.val == key) {
            head = head.next;
            return;
        }
        Node cur = searchPrev(key);
        //没有你要删除的数据
        if(cur == null) {
            return;
        }
        Node del = cur.next;//要删除的节点
        cur.next = del.next;
    }

    /**
     * 找到关键字key的前一个节点
     * @param key
     * @return
     */
    private Node searchPrev(int key) {
        Node cur = head;
        while (cur.next != null) {
            if(cur.next.val == key) {
                return cur;
            }
            cur = cur.next;
        }
        return null;//没有你要删除的节点
    }

    public void clear() {
        head = null;
    }

}

以上为我个人的小分享,如有问题,欢迎讨论!!!

都看到这了,不如关注一下,给个免费的赞

相关推荐
考虑考虑4 小时前
Jpa使用union all
java·spring boot·后端
用户3721574261354 小时前
Java 实现 Excel 与 TXT 文本高效互转
java
浮游本尊5 小时前
Java学习第22天 - 云原生与容器化
java
渣哥7 小时前
原来 Java 里线程安全集合有这么多种
java
间彧7 小时前
Spring Boot集成Spring Security完整指南
java
间彧7 小时前
Spring Secutiy基本原理及工作流程
java
Java水解8 小时前
JAVA经典面试题附答案(持续更新版)
java·后端·面试
洛小豆11 小时前
在Java中,Integer.parseInt和Integer.valueOf有什么区别
java·后端·面试
前端小张同学11 小时前
服务器上如何搭建jenkins 服务CI/CD😎😎
java·后端
ytadpole11 小时前
Spring Cloud Gateway:一次不规范 URL 引发的路由转发404问题排查
java·后端