Java链表(Linked List)基本原理与实现方法入门示例

下面是Java链表(Linked List)基本原理与实现方法入门示例的完整攻略。

什么是链表

链表是一种线性的数据结构,由一系列节点组成。每个节点都包含了数据和指向下一个节点的指针。

相比于数组,链表的一个主要优点是在插入、删除元素时不需要移动其他元素,因为每个节点都有指向下一个节点的指针。但是,链表的缺点是不能像数组一样随机访问,只能从头部开始遍历。

实现方法

Java实现单向链表

Java实现单向链表需要定义一个Node类,用于表示链表中的节点。定义一个链表类LinkedList,拥有添加节点方法(addNode)、删除节点方法(deleteNode)、遍历节点方法(traverseNodes)、清空链表方法等方法。

例如,以下为Java实现单向链表的示例代码:

public class Node {
    int data;
    Node next;

    public Node(int data) {
        this.data = data;
    }
}

public class LinkedList {
    Node head;

    public void addNode(int data) {
        Node newNode = new Node(data);
        if (head == null) {
            head = newNode;
        } else {
            Node current = head;
            while (current.next != null) {
                current = current.next;
            }
            current.next = newNode;
        }
    }

    public void deleteNode(int data) {
        Node current = head;
        Node previous = null;
        while (current != null && current.data != data) {
            previous = current;
            current = current.next;
        }
        if (current != null) {
            if (previous == null) {
                head = current.next;
            } else {
                previous.next = current.next;
            }
        }
    }

    public void traverseNodes() {
        Node current = head;
        while (current != null) {
            System.out.println(current.data);
            current = current.next;
        }
    }

    public void clearList() {
        head = null;
    }
}

Java实现双向链表

Java实现双向链表需要在Node类中再添加前驱节点(previous)的指针,链表类中添加反向遍历节点方法(reverseTraverseNodes),其他方法和单向链表的实现类似。

例如,以下为Java实现双向链表的示例代码:

public class Node {
    int data;
    Node next;
    Node previous;

    public Node(int data) {
        this.data = data;
    }
}

public class DoublyLinkedList {
    Node head;

    public void addNode(int data) {
        Node newNode = new Node(data);
        if (head == null) {
            head = newNode;
        } else {
            Node current = head;
            while (current.next != null) {
                current = current.next;
            }
            current.next = newNode;
            newNode.previous = current;
        }
    }

    public void deleteNode(int data) {
        Node current = head;
        while (current != null && current.data != data) {
            current = current.next;
        }
        if (current != null) {
            if (current.previous == null) {
                head = current.next;
                if (head != null) {
                    head.previous = null;
                }
            } else {
                current.previous.next = current.next;
                if (current.next != null) {
                    current.next.previous = current.previous;
                }
            }
        }
    }

    public void traverseNodes() {
        Node current = head;
        while (current != null) {
            System.out.println(current.data);
            current = current.next;
        }
    }

    public void reverseTraverseNodes() {
        Node current = head;
        while (current.next != null) {
            current = current.next;
        }
        while (current != null) {
            System.out.println(current.data);
            current = current.previous;
        }
    }

    public void clearList() {
        head = null;
    }
}

示例说明

以下为使用单向链表实现LIFO(后进先出)栈的示例代码:

public class Stack {
    LinkedList list;

    public Stack() {
        list = new LinkedList();
    }

    public void push(int data) {
        list.addNode(data);
    }

    public int pop() {
        Node current = list.head;
        if (current == null) {
            throw new NoSuchElementException();
        } else if (current.next == null) {
            list.head = null;
            return current.data;
        } else {
            while (current.next.next != null) {
                current = current.next;
            }
            int data = current.next.data;
            current.next = null;
            return data;
        }
    }

    public void printStack() {
        list.traverseNodes();
    }
}

使用方式:

Stack stack = new Stack();
stack.push(1);
stack.push(2);
stack.push(3);  // 栈中元素为 3 -> 2 -> 1
stack.pop();    // 弹出元素3,栈中元素为 2 -> 1
stack.push(4);  // 栈中元素为 4 -> 2 -> 1
stack.printStack();  // 输出 4 2 1

以下为使用双向链表实现LIFO(后进先出)队列的示例代码:

public class Queue {
    DoublyLinkedList list;

    public Queue() {
        list = new DoublyLinkedList();
    }

    public void enqueue(int data) {
        list.addNode(data);
    }

    public int dequeue() {
        Node current = list.head;
        if (current == null) {
            throw new NoSuchElementException();
        } else if (current.next == null) {
            list.head = null;
            return current.data;
        } else {
            list.head = current.next;
            current.next.previous = null;
            return current.data;
        }
    }

    public void printQueue() {
        list.traverseNodes();
    }
}

使用方式:

Queue queue = new Queue();
queue.enqueue(1);
queue.enqueue(2);
queue.enqueue(3);  // 队列中元素为 1 <- 2 <- 3
queue.dequeue();   // 弹出元素1,队列中元素为 2 <- 3
queue.enqueue(4);  // 队列中元素为 2 <- 3 <- 4
queue.printQueue();  // 输出 2 3 4

以上两个示例代码对于链表的基本操作进行了展示,并且演示了如何通过链表实现栈和队列。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java链表(Linked List)基本原理与实现方法入门示例 - Python技术站

(0)
上一篇 2023年5月26日
下一篇 2023年5月26日

相关文章

  • 一文探究ArrayBlockQueue函数及应用场景

    一文探究ArrayBlockingQueue函数及应用场景 介绍 ArrayBlockingQueue是Java中的一个阻塞队列实现类,它是一个支持在队列的两端插入和删除元素的线程安全队列。它的大小是有限的,当队列已满时,插入操作会阻塞线程,直到队列有空闲空间;当队列为空时,获取操作会阻塞线程,直到队列有可用元素。 使用方法 创建ArrayBlockingQ…

    Java 2023年5月26日
    00
  • Java获取文件的路径及常见问题解决方案

    关于Java获取文件的路径及常见问题解决方案,下面是详细的攻略。 1. Java获取文件的路径 在Java中获取文件的路径是非常常见的需求,可以使用以下几种方式来获取: 1.1 获取当前运行的Java程序所在路径 String path = System.getProperty("user.dir"); 使用System.getPrope…

    Java 2023年5月20日
    00
  • Java日常练习题,每天进步一点点(53)

    Java日常练习题,每天进步一点点(53) 这是一组Java练习题,旨在帮助Java初学者提高编程能力。在本文中,我们将详细讲解Java日常练习题,并提供两个示例来说明如何解决这些问题。 练习题 编写一个Java程序,计算1到100之间所有偶数的和。 编写一个Java程序,将一个字符串中的所有空格去掉。 编写一个Java程序,判断一个字符串是否为回文字符串。…

    Java 2023年5月18日
    00
  • Jackson序列化丢失泛型的解决

    在Java中,使用Jackson库进行序列化和反序列化是非常常见的。然而,当我们使用泛型时,Jackson序列化可能会丢失泛型信息,导致反序列化时出现问题。在本文中,我们将详细讲解如何解决Jackson序列化丢失泛型的问题,并提供两个示例来说明如何使用这些方法。 问题描述 当我们使用泛型时,Jackson序列化可能会丢失泛型信息。例如,考虑以下示例: pub…

    Java 2023年5月18日
    00
  • JavaScript继承与聚合实例详解

    JavaScript继承与聚合是面向对象编程中常用的两种对象复用技巧。在本文中,我们将详细讲解这两种技巧的实现方式,并通过两个示例说明其使用方法及优缺点。 一、JavaScript继承 继承是面向对象编程中一个重要的概念,它可以让子类继承父类的属性和行为。在JavaScript中,我们可以使用原型链来实现继承。 利用原型链继承 原型链继承是JavaScrip…

    Java 2023年5月26日
    00
  • SpringBoot整合Swagger框架过程解析

    下面为您详细讲解“SpringBoot整合Swagger框架过程解析”的完整攻略。 什么是Swagger? Swagger是一个开源框架,旨在简化 RESTful Web 服务的开发和文档化,它可以生成能描述API的 JSON、HTML等文档。它包含了一些工具,可以帮助开发人员设计、构建、文档化和使用 RESTful Web 服务。 SpringBoot整合…

    Java 2023年5月19日
    00
  • sprintboot使用spring-security包,缓存内存与redis共存方式

    Spring Boot 使用 Spring Security 包,缓存内存与 Redis 共存方式 背景 在使用 Spring Boot 进行 Web 开发时,很常用到 Spring Security 框架来支持身份验证、授权等功能。同时,为了提高网站的性能,常使用缓存来减少数据库的访问次数。其中常用的缓存方式包括内存缓存和 Redis 缓存。本文将详细讲解…

    Java 2023年5月20日
    00
  • Springboot框架实现自动装配详解

    Spring Boot框架实现自动装配详解 Spring Boot是一个非常流行的Java框架,它可以帮助开发人员快速构建基于Spring的应用程序。其中一个最重要的特性就是自动装配。在本文中,我们将详细讲解Spring Boot框架实现自动装配的过程和原理,并提供两个示例来演示如何使用自动装配。 自动装配的原理 自动装配是Spring Boot框架的核心特…

    Java 2023年5月15日
    00
合作推广
合作推广
分享本页
返回顶部