链表--java实现

本文详细介绍了链表这种数据结构的四种类型:单向链表、双端链表、有序链表和双向链表。每种链表都包括基本概念、实现原理及核心操作如插入、删除等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

链表(Linked List)

链表Linked list)是一种常见的基础数据结构,是一种线性表,但是并不会按线性的顺序存储数据,而是在每一个节点里存到下一个节点的指针(Pointer)。

  使用链表结构可以克服数组链表需要预先知道数据大小的缺点,链表结构可以充分利用计算机内存空间,实现灵活的内存动态管理。但是链表失去了数组随机读取的优点,同时链表由于增加了结点的指针域,空间开销比较大。

一,单向链表(Single Linked List)

单链表是链表中结构最简单的。一个单链表的节点(Node)分为两个部分,第一个部分(data)保存或者显示关于节点的信息,另一个部分存储下一个节点的地址。最后一个节点存储地址的部分指向空值。

  单向链表只可向一个方向遍历,一般查找一个节点的时候需要从第一个节点开始每次访问下一个节点,一直访问到需要的位置。而插入一个节点,对于单向链表,我们只提供在链表头插入,只需要将当前插入的节点设置为头节点,next指向原头节点即可。删除一个节点,我们将该节点的上一个节点的next指向该节点的下一个节点。

SingleLinkedList.java

package LinkedList;

public class SingleLinkedList<E> {
    private class Node<E>{
        private E data;
        private Node next;

        public Node(E data) {
            this.data = data;
        }
    }
    private int size;
    private Node head;

    public SingleLinkedList(){
        int size = 0;
        head = null;
    }

    //在链表头添加元素
    public Object add(E e){
        Node node = new Node(e);
        if(size == 0){
            head = node;
        }
        else{
            node.next = head;
            head = node;
        }
        size++;
        return e;
    }
    //在链表头删除元素
    public E delete(){
        E  e = (E) head.data;
        head = head.next;
        size--;
        return e;
    }
    //查找指定元素,返回,如果无,返回null
    public E find(E e){
        Node currentNode = head;
        int temp = size;
        while(temp>0){
            if(e.equals(head.data)){
                return (E) currentNode;
            }
            else{
                currentNode = currentNode.next;
            }
            temp--;
        }
        return null;
    }

    //删除指定元素
    public boolean delete(E e){
        if(size == 0){
            throw new RuntimeException("链表为空");
        }
        else{
            Node current = head;
            Node previous = head;
            while (current.data != e){
                if(current.next == null){
                    return false;
                }
                else{
                    previous = current;
                    current = current.next;
                }
            }
            if(current == head){
                head = current.next;
                size--;
            }
            else{
                previous.next=current.next;
                size--;
            }
            return true;
        }
    }
    //判空
    public boolean empty(){
        return size==0?true:false;
    }
    //显示节点信息
    public void show(){
        if(size>0){
            Node current = head;
            int temp =size;
            while (temp!=0){
                //System.out.println(temp);
                if(temp==size){
                    System.out.print("["+current.data+">");
                    current = current.next;
                }
                else if(temp==1){
                    System.out.print(current.data+"]");
                }
                else{
                    System.out.print(current.data+">");
                    current = current.next;
                }
                temp--;
            }
        }
    }

    public static void main(String[] args) {
        SingleLinkedList sll = new SingleLinkedList();
        sll.add("a");
        sll.add("b");
        sll.add("c");
        sll.add("d");
        sll.show();

        sll.delete();

        sll.show();

        sll.delete("b");

        sll.show();
    }

}

二,双端链表(Double Point Linked List)

对于单项链表,我们如果想在尾部添加一个节点,那么必须从头部一直遍历到尾部,找到尾节点,然后在尾节点后面插入一个节点。这样操作很麻烦,如果我们在设计链表的时候多个对尾节点的引用,那么会简单很多。

package LinkedList;

public class DoublePointLinkedList<E> {
    private class Node<E>{
        private E data;
        private Node next;

        public Node(E data) {
            this.data = data;
        }
    }
    private Node head;
    private Node rear;
    private int size;

    public DoublePointLinkedList() {
        size=0;
        head = rear = null;
    }

    public E addHead(E e){
        Node node = new Node(e);
        if(size==0){
            head = rear = node;
        }
        else{
            node.next = head;
            head = node;
        }
        size++;
        return e;
    }
    //在尾部添加元素
    public E addRear(E e){
        Node node  = new Node(e);
        if(size==0){
            head = rear = node;
        }
        else{
            rear.next = node;
            node.next=head;
            rear = node;
        }
        size++;
        return e;
    }
    //删除头节点
    public void deleteHead(){
        if(size==0){
            throw new RuntimeException("链表为空");
        }
        else{
            rear.next = head.next;
            head=head.next;
        }
        size--;
    }
    //显示节点信息
    public void show(){
        if(size>0){
            Node current = head;
            int temp =size;
            while (temp!=0){
                //System.out.println(temp);
                if(temp==size){
                    System.out.print("["+current.data+">");
                    current = current.next;
                }
                else if(temp==1){
                    System.out.print(current.data+"]");
                }
                else{
                    System.out.print(current.data+">");
                    current = current.next;
                }
                temp--;
            }
        }
    }

    public static void main(String[] args) {
        DoublePointLinkedList dpll = new DoublePointLinkedList();
        dpll.addHead("a");
        dpll.addHead("b");
        dpll.addHead("c");
        dpll.show();
        dpll.addRear("d");
        dpll.deleteHead();
        dpll.show();
    }
}

三,有序链表(Order Linked List)

前面的链表实现插入数据都是无序的,在有些应用中需要链表中的数据有序,这称为有序链表。

  在有序链表中,数据是按照关键值有序排列的。一般在大多数需要使用有序数组的场合也可以使用有序链表。有序链表优于有序数组的地方是插入的速度(因为元素不需要移动),另外链表可以扩展到全部有效的使用内存,而数组只能局限于一个固定的大小中。

package LinkedList;

public class OrderLinkedList {
    private class Node{
        private int data;
        private Node next;

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

    public OrderLinkedList() {
        size=0;
        head=null;
    }

    public void add(int value) {//3281
        Node node = new Node(value);
        Node currentNode = head;
        Node previousNode = null;
        while (currentNode != null && value>currentNode.data) {
            previousNode = currentNode;
            currentNode = currentNode.next;
        }
        if(previousNode == null){
            head = node;
            head.next=currentNode;
        }
        else{
            previousNode.next=node;
            node.next=currentNode;
        }
        size++;
        //System.out.println(value);
    }

    //删除头节点
    public void delete(){
        head = head.next;
    }

    //display
    public void display(){
        Node currentNode = head;
        while (currentNode != null){
            System.out.print(currentNode.data+"  ");
            currentNode = currentNode.next;
        }
        System.out.println();
    }

    //测试方法
    public static void main(String[] args) {
        OrderLinkedList oll = new OrderLinkedList();
        oll.add(3);
        oll.add(2);
        oll.add(8);
        oll.add(1);

        oll.display();
        oll.delete();
        oll.display();
    }
}

四,双向链表(Two Way Linked List)

单向链表只能从一个方向遍历,那么双向链表它可以从两个方向遍历。

package LinkedList;

public class TwoWayLinkedList<E> {
    private class Node<E>{
        private E data;
        private Node previous;
        private Node next;

        public Node(E data) {
            this.data = data;
        }
    }
    private Node head;
    private Node rear;
    private int size;

    public TwoWayLinkedList() {
        size=0;
        head = rear =null;
    }

    //表头添加
    public void addHead(E e){
        Node node = new Node(e);
        if(size==0){
            head = rear = node;
        }
        else{
            node.next=head;
            head.previous = node;
            head = node;
        }
        size++;
    }
    //表尾添加
    public void addRear(E e){
        Node node = new Node(e);
        if(size==0){
            head = rear = node;
        }
        else{
            rear.next = node;
            node.previous = rear;
            rear = node;
        }
        size++;
    }
    //删除头
    public boolean deleteHead(){
        if(size == 0){
            throw new RuntimeException("链表为空");
        }
        else{
            head = head.next;
            head.previous = null;
            size--;
            return true;
        }
    }
    public boolean deleteRear(){
        if(size == 0){
            throw new RuntimeException("链表为空");
        }
        else{
            rear = rear.previous;
            rear.next = null;
            size--;
            return true;
        }
    }
    //显示节点
    public void display(){
        Node currentNode = head;
        while (currentNode != null){
            System.out.print(currentNode.data+"  ");
            currentNode = currentNode.next;
        }
        System.out.println();
    }
    //测试方法
    public static void main(String[] args) {
        TwoWayLinkedList twll = new TwoWayLinkedList();
        twll.addHead("a");
        twll.addHead("b");
        twll.addRear("1");
        twll.addHead("2");

        twll.display();
        twll.deleteHead();
        twll.display();
        twll.deleteRear();
        twll.display();
    }
}

资源下载链接为: https://pan.quark.cn/s/22ca96b7bd39 在当今的软件开发领域,自动化构建与发布是提升开发效率和项目质量的关键环节。Jenkins Pipeline作为一种强大的自动化工具,能够有效助力Java项目的快速构建、测试及部署。本文将详细介绍如何利用Jenkins Pipeline实现Java项目的自动化构建与发布。 Jenkins Pipeline简介 Jenkins Pipeline是运行在Jenkins上的一套工作流框架,它将原本分散在单个或多个节点上独立运行的任务串联起来,实现复杂流程的编排与可视化。它是Jenkins 2.X的核心特性之一,推动了Jenkins从持续集成(CI)向持续交付(CD)及DevOps的转变。 创建Pipeline项目 要使用Jenkins Pipeline自动化构建发布Java项目,首先需要创建Pipeline项目。具体步骤如下: 登录Jenkins,点击“新建项”,选择“Pipeline”。 输入项目名称和描述,点击“确定”。 在Pipeline脚本中定义项目字典、发版脚本和预发布脚本。 编写Pipeline脚本 Pipeline脚本是Jenkins Pipeline的核心,用于定义自动化构建和发布的流程。以下是一个简单的Pipeline脚本示例: 在上述脚本中,定义了四个阶段:Checkout、Build、Push package和Deploy/Rollback。每个阶段都可以根据实际需求进行配置和调整。 通过Jenkins Pipeline自动化构建发布Java项目,可以显著提升开发效率和项目质量。借助Pipeline,我们能够轻松实现自动化构建、测试和部署,从而提高项目的整体质量和可靠性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值