链表的顶级理解

目录

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;
    }

}

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

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

相关推荐
李慕婉学姐6 小时前
【开题答辩过程】以《基于JAVA的校园即时配送系统的设计与实现》为例,不知道这个选题怎么做的,不知道这个选题怎么开题答辩的可以进来看看
java·开发语言·数据库
孙严Pay6 小时前
快捷支付:高效安全的在线支付新选择
笔记·科技·计算机网络·其他·微信
POLITE36 小时前
Leetcode 23. 合并 K 个升序链表 (Day 12)
算法·leetcode·链表
zhongvv7 小时前
8位应广单片机与32位M0单片机开发差异总结
经验分享·单片机·嵌入式硬件
奋进的芋圆7 小时前
Java 延时任务实现方案详解(适用于 Spring Boot 3)
java·spring boot·redis·rabbitmq
sxlishaobin8 小时前
设计模式之桥接模式
java·设计模式·桥接模式
model20058 小时前
alibaba linux3 系统盘网站迁移数据盘
java·服务器·前端
荒诞硬汉8 小时前
JavaBean相关补充
java·开发语言
提笔忘字的帝国8 小时前
【教程】macOS 如何完全卸载 Java 开发环境
java·开发语言·macos
2501_941882488 小时前
从灰度发布到流量切分的互联网工程语法控制与多语言实现实践思路随笔分享
java·开发语言