JAVA 数据结构链表操作循环链表

yizhihongxing

JAVA 数据结构链表操作循环链表

什么是链表

链表(Linked List)是一种常见的基础数据结构,它可以存储一个线性序列,但与数组不同的是,链表中的元素并不是在内存中连续存储的,而是通过指针将它们链接在一起。

链表由一系列节点组成,每个节点包含两部分:数据和指向下一节点的指针。最后一个节点的指针指向 NULL 表示链表的结尾。

链表常见的操作有:插入、删除、查找、遍历等。其中,插入和删除操作是链表的特点之一,因为链表中的元素并不是在内存中连续存储的,对于插入和删除操作并没有数组那样的位移操作,这也使得链表的插入和删除操作效率比数组高。而查找和遍历操作则需要使用指针进行相应的操作。

常见的链表类型

在链表的实现中,有两种常见的类型:单向链表和双向链表。它们的区别在于节点的指针个数不同,单向链表只有指向下一节点的指针,而双向链表有指向下一节点和前一节点的指针。

此外,在循环链表中,最后一个节点的指针不为 NULL,而是指向链表的头节点,这样链表的开头和结尾就可以随意切换,可以实现循环递归操作。

JAVA 中的链表实现

JAVA 中的链表可以通过自己的类来实现,也可以使用 JAVA 中提供的集合类来实现。对于后者,常见的链表类有 LinkedList 和 ArrayDeque。

LinkedList 类实现了 List 接口,它包含了双向链表的实现,同时还实现了 Queue 接口,可以当作队列来使用。

ArrayDeque 类同样实现了 Queue 接口,它使用数据结构双端队列来实现,操作效率比 LinkedList 更高。

以下为在 Java 中使用链表模拟循环队列的示例代码:

import java.util.LinkedList;
import java.util.Queue;

public class CircularQueue {
    private int size;

    private Queue<Integer> queue;

    public CircularQueue(int size) {
        this.size = size;
        this.queue = new LinkedList<>();
    }

    public boolean enQueue(int value) {
        if (queue.size() == size) {
            return false;
        }
        queue.add(value);
        return true;
    }

    public boolean deQueue() {
        if (queue.isEmpty()) {
            return false;
        }
        queue.remove();
        return true;
    }

    public int Front() {
        if (queue.isEmpty()) {
            return -1;
        }
        return queue.peek();
    }

    public int Rear() {
        if (queue.isEmpty()) {
            return -1;
        }
        return ((LinkedList<Integer>) queue).getLast();
    }

    public boolean isEmpty() {
        return queue.isEmpty();
    }

    public boolean isFull() {
        return queue.size() == size;
    }
}

链表操作循环链表的示例

示例1:Java 实现循环链表

public class Node {
    int val;

    Node next;

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

public class CircleLinkList {

    private Node head;

    public CircleLinkList(int num) {
        this.head = null;
        if (num > 0) {
            Node pre = null;
            for (int i = 1; i <= num; i++) {
                Node cur = new Node(i);
                if (head == null) {
                    head = cur;
                } else {
                    pre.next = cur;
                }
                pre = cur;
            }
            pre.next = head;
        }
    }

    public int size() {
        int size = 0;
        Node cur = head;
        while (cur != null && (cur.next != head || size == 0)) {
            size++;
            cur = cur.next;
        }
        return size;
    }

    public int get(int index) {
        Node cur = head;
        int count = 0;
        while (cur != null && (cur.next != head || count == 0)) {
            if (count == index) {
                return cur.val;
            }
            count++;
            cur = cur.next;
        }
        return -1;
    }

    public void visualize() {
        Node cur = head;
        while (cur != null && cur.next != head) {
            System.out.print(cur.val + "->");
            cur = cur.next;
        }
        if (cur != null) {
            System.out.print(cur.val);
        }
        System.out.println();
    }
}

以上代码实现了一个循环链表,通过构造方法创建了一个 num 个节点的循环链表。size() 方法用于获取循环链表的长度,get(int index) 方法用于获取循环链表中对应索引位置的元素,visualize() 方法用于将循环链表进行输出。

示例2:Java 实现链表加法

public class ListNode {
    int val;
    ListNode next;

    public ListNode(int x) {
        val = x;
    }
}

public class Solution {
    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        ListNode head = null, tail = null;
        int carry = 0;
        while (l1 != null || l2 != null) {
            int n1 = l1 != null ? l1.val : 0;
            int n2 = l2 != null ? l2.val : 0;
            int sum = n1 + n2 + carry;
            if (head == null) {
                head = tail = new ListNode(sum % 10);
            } else {
                tail.next = new ListNode(sum % 10);
                tail = tail.next;
            }
            carry = sum / 10;
            if (l1 != null) {
                l1 = l1.next;
            }
            if (l2 != null) {
                l2 = l2.next;
            }
        }
        if (carry > 0) {
            tail.next = new ListNode(carry);
        }
        return head;
    }
}

以上代码实现了两个链表的加法操作,将两个链表中的元素进行加法运算,得到结果链表。其中,l1 和 l2 为两个链表的头节点,head 和 tail 分别表示结果链表的头节点和尾节点,carry 表示进位,while 循环用于遍历链表进行加法运算。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:JAVA 数据结构链表操作循环链表 - Python技术站

(0)
上一篇 2023年6月27日
下一篇 2023年6月27日

相关文章

  • 苹果iOS10 Beta3开发者预览版固件下载地址汇总(附升级方法)

    苹果iOS10 Beta3开发者预览版固件下载及升级方法 苹果iOS10 Beta 3开发者预览版固件已经发布了,以下是固件下载地址及升级方法的详细攻略。 下载地址 在下载之前,请确保你已经注册了苹果开发者账号。 前往 https://developer.apple.com/download/ ,登录 Apple Developer Center。 选择 “…

    other 2023年6月26日
    00
  • SQL Server 2012 安装图解教程(附sql2012下载地址)

    SQL Server 2012 安装图解教程(附sql2012下载地址) 1. 下载 SQL Server 2012 首先,在Microsoft官网上下载SQL Server 2012的安装程序。在此过程中需要输入有效的Windows账户以获取安装文件。 2. 运行安装程序 运行安装程序以开始SQL Server 2012的安装过程。选择安装类型(典型、完全…

    other 2023年6月27日
    00
  • nsnumber与nsinteger的区别-bei

    以下是“NSNumber与NSInteger的区别”的完整攻略: NSNumber与NSInteger的区别 NSNumber和NSInteger都是Objective-C中的数据类型,但它们有不同的用途和特点。本攻略将介NSNumber和NSInteger的区别。 NSNumber NSNumber是Objective-C中的一个类,用于封装基本数据类型,…

    other 2023年5月7日
    00
  • 聊一聊前端算法面试(递归)

    聊一聊前端算法面试(递归) 什么是递归 递归(Recursion)是指函数直接或间接地调用自身的方法。在计算机科学中,递归的使用十分广泛,例如快速排序、求阶乘、二分查找等算法都是递归的。 递归函数一般具有如下特点: 基线条件:函数的结束函数,使用 if 语句来判断是否结束递归。 递归条件:函数调用自己的条件。 自己调用自己:函数的最后一句代码应是调用自身。 …

    other 2023年6月27日
    00
  • 微信小程序列表时间戳转换实现过程解析

    微信小程序列表时间戳转换实现过程解析 在微信小程序中,通常会从后端接口获取到时间戳数据,而在前端展示时,我们通常需要将时间戳转换为可读的日期格式。下面是实现时间戳转换的完整过程解析。 步骤一:获取时间戳数据 首先,从后端接口获取到时间戳数据,可以通过调用接口的方式获取到一个包含时间戳的列表数据。 示例代码: // 调用后端接口获取时间戳数据 wx.reque…

    other 2023年10月17日
    00
  • c++性能剖析教程之循环展开

    C++性能剖析教程之循环展开 循环展开是一种优化技术,可以通过减少循环迭代次数来提高程序的性能。在本文中,我们将介绍如何使用循环展开来优化C++代码,并提供一些示例说明。 循环展开的原理 循环展开是一种优化技术,它通过减少循环迭代次数来提高程序的性能。循环展开的原理是将循环体中的代码复制多次,以减少循环迭代的次数。例如,如果我们有一个循环迭代10次,循环体中…

    other 2023年5月8日
    00
  • springboot父子项目的搭建(idea搭建)

    Spring Boot父子项目的搭建(IDEA搭建) Spring Boot是一个快速开发框架,可以帮助开发人员快速构建基于Spring的应用程序。在实际开发中,我们可能需要创建一个父子项目的结构,以便更好地组织代码和管理依赖项。本攻略将详细讲解如何使用IDEA创建Spring Boot父子项目的结构。 步骤 以下是使用IDEA创建Spring Boot父子…

    other 2023年5月8日
    00
  • C语言由浅入深讲解文件的操作上篇

    下面是“C语言由浅入深讲解文件的操作上篇”的完整攻略,包含了文件的基本概念以及如何进行文件的操作。 文件的基本概念 在C语言中,文件指的是存储在硬盘或其他存储设备上的可以被读取和写入的数据。文件是以二进制形式存储的,可以包含文本、图像、视频等数据。 在C语言中,可以使用标准库中的文件操作函数对文件进行读写操作。常用的文件操作函数包括fopen、fclose、…

    other 2023年6月26日
    00
合作推广
合作推广
分享本页
返回顶部