• 浅谈数据结构之链表


    链表是一种灵活的数据结构,有单向链表、双向链表和循环链表等多种形式。在本文中,我们将深入探讨单向链表、双向链表、循环链表的定义、Java实现方式、使用场景,同时比较它们的不同之处。我们还会介绍链表与队列之间的区别。

    单向链表

    定义

    单向链表是由节点组成的数据结构,每个节点包含数据和指向下一个节点的指针。链表的头节点指向第一个节点,而最后一个节点的指针指向空值(null)。

    Java实现

    以下是使用Java实现单向链表的简单示例:

    public class ListNode {
        int data;
        ListNode next;
    
        public ListNode(int data) {
            this.data = data;
            this.next = null;
        }
    }
    
    public class LinkedList {
        ListNode head;
    
        public LinkedList() {
            this.head = null;
        }
    
        // 添加节点到链表尾部
        public void append(int data) {
            ListNode newNode = new ListNode(data);
            if (head == null) {
                head = newNode;
                return;
            }
            ListNode current = head;
            while (current.next != null) {
                current = current.next;
            }
            current.next = newNode;
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    双向链表

    定义

    双向链表是单向链表的扩展,每个节点不仅包含指向下一个节点的指针,还包含指向前一个节点的指针。这使得在双向链表中,可以在节点之间双向移动。

    Java实现

    以下是使用Java实现双向链表的简单示例:

    public class DoubleListNode {
        int data;
        DoubleListNode prev;
        DoubleListNode next;
    
        public DoubleListNode(int data) {
            this.data = data;
            this.prev = null;
            this.next = null;
        }
    }
    
    public class DoublyLinkedList {
        DoubleListNode head;
    
        public DoublyLinkedList() {
            this.head = null;
        }
    
        // 在链表头部插入节点
        public void prepend(int data) {
            DoubleListNode newNode = new DoubleListNode(data);
            if (head != null) {
                head.prev = newNode;
            }
            newNode.next = head;
            head = newNode;
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    循环链表

    定义

    循环链表是一种特殊形式的链表,其中最后一个节点的指针指向链表的头部,形成一个循环。这使得链表可以无限循环下去。

    Java实现

    以下是使用Java实现循环链表的简单示例:

    public class CircularListNode {
        int data;
        CircularListNode next;
    
        public CircularListNode(int data) {
            this.data = data;
            this.next = null;
        }
    }
    
    public class CircularLinkedList {
        CircularListNode head;
    
        public CircularLinkedList() {
            this.head = null;
        }
    
        // 添加节点到循环链表尾部
        public void append(int data) {
            CircularListNode newNode = new CircularListNode(data);
            if (head == null) {
                head = newNode;
                head.next = head;  // 将最后一个节点的指针指向头部,形成循环
                return;
            }
            CircularListNode current = head;
            while (current.next != head) {
                current = current.next;
            }
            current.next = newNode;
            newNode.next = head;
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    使用场景

    单向链表

    • 资源共享:单向链表可用于实现多个部分之间的资源共享,其中每个节点表示一个资源。
    • 缓存实现:单向链表可用于实现缓存,其中新数据可以在链表的头部迅速插入,而最久未使用的数据则可以在链表尾部删除。

    双向链表

    • 前后导航:双向链表允许在节点之间前后导航,使其适用于需要双向遍历的场景,如文本编辑器的光标移动。
    • LRU缓存:双向链表可用于实现LRU(Least Recently Used)缓存,其中最近访问的数据位于链表的头部,而最久未使用的数据位于链表尾部。

    循环链表

    • 轮流执行:循环链表可用于轮流执行任务,如操作系统中的进程调度。
    • 循环队列:循环链表可以用于实现循环队列,如生产者-消费者模型中的任务调度。

    时间复杂度

    单向链表、双向链表和循环链表

    • 访问(Access) :O(n) - 在链表中查找特定节点的时间复杂度是线性的。
    • 插入(Insertion) :O(1) - 在链表中插入节点的时间复杂度是常数。
    • 删除(Deletion) :O(1) - 在链表中删除节点的时间复杂度是常数。

    比较单向链表、双向链表和循环链表

    1. 内存使用:双向链表和循环链表需要额外的空间存储前一个节点的引用,因此相较于单向链表,它们的内存消耗更大。
    2. 操作灵活性:双向链表在操作上更为灵活,因为它可以轻松地在节点之间进行双向遍历。循环链表允许无限循环,适用于轮流执行的场景。

    链表与队列的区别

    链表和队列是两种不同的数据结构,主要区别在于它们的目的和操作方式。

    • 链表:链表是一种数据结构,用于表示元素之间的线性关系。它支持灵活的插入和删除操作,并且可以在任意位置添加或删除元素。
    • 队列:队列是一种数据结构,用于按顺序存储和访问元素。它遵循“先进先出”(FIFO)原则,即最早入队的元素将最早出队。

    在队列中,元素只能在队尾入队,在队头出队。而链表则允许在任意位置插入或删除元素。虽然队列可以使用链表实现,但它们是两个不同的概念,适用于不同的应用场景。

    总结

    链表是一种灵活的数据结构,有单向链表、双向链表和循环链表等多种形式。单向链表适用于简单的前后遍历场景,而双向链表在需要前后导航和更复杂的应用场景中表现出色。循环链表允许无限循环,适用于需要轮流执行任务的场景。链表的实现相对简单,它在访问、插入和删除方面具有良好的性能。链表与队列有相似之处,但它们在目的和操作方式上有明显的区别。了解链表的不同形式以及它们的应用和性能特点,有助于更好地选择和使用这一重要的数据结构。

  • 相关阅读:
    想要精通算法和SQL的成长之路 - K次取反后最大化的数组和
    一篇看懂C#中的Task任务_初级篇
    zsh: command not found: conda问题解决
    科技的成就(三十四)
    数据结构之栈
    我的DW个人网站设计——安徽宣城6页HTML+CSS+JavaScript
    QGIS开发笔记(三):Windows安装版二次开发环境搭建(下):将QGis融入QtDemo,添加QGis并加载tif遥感图的Demo
    关于五度圈
    排序算法详解
    复杂网络 | 利用复杂网络预测城市空间流量
  • 原文地址:https://blog.csdn.net/oZhuiMeng123/article/details/134322300