基于JAVA的单向链表反转,删除节点,列表去重,合并链表

一、链表的基本概述

1.结构:

由节点(Node)构成,每个节点包含数据域指针域。指针域指向下一个节点(单链表)、前/后节点(双链表)或头节点(循环链表)。

2.类型:

(1)单链表:每个节点仅包含一个值和指向后继的指针。

(2)双链表:节点包含前驱指针和后继指针,支持双向遍历。

(3)环形链表:尾节点的指针指向头节点形成闭环。

3.与数组相比:

优势:动态大小、高效插入/删除(时间复杂度O(1))

劣势:随机访问,跟数组不一样,数组有索引,可以直接访问(遍历的时间复杂度O(n))

二、核心操作与算法

1,链表的类型

(1)单向链表
public class Listcode {

    public int val;

    public Listcode next;

    public Listcode(int val, Listcode next) {
       this.val = val;
       this.next = next;
    }
}

该类定义了每个节点中都必须存在一个数据和一个指向后继的指针,还有一个用于构造节点的构造器。

(2)双向链表
public class Listcode {
    public int val;
    public Listcode last;
    public Listcode next;
    public Listcode(int val, Listcode next,Listcode last) {
       this.val = val;
       this.last = last;
       this.next = next;
    }
}

双向链表较单向链表的区别就是多一个指向上一个节点的前驱指针。

(3)环形链表

环形链表就是最后一个节点的指针不再指向空值null,而是指向头节点。

2.链表的特殊操作

(1)单向链表的反转
 public ListNode reverseList(ListNode o1) {
        ListNode n1 = null;
        ListNode p = o1;
        while(p !=null){
            n1=new ListNode(p.val,n1);
            p = p.next;
        }
        return n1;
    }

采用的是创建一个新的链表,然后将原来链表中的节点的第一个加到新的链表末尾,然后逐个依次重复。

(2)删除链表倒数第几个节点
 public ListNode removeNthFromEnd(ListNode head, int n) {
        ListNode s =new ListNode(-1,head);
        ListNode p1=s;
        ListNode p2=s;
        for(int i=0;i

这段代码实现了一个函数`removeNthFromEnd`,用于从链表的末尾移除第n个节点。通过使用两个指针p1和p2,其中p2先移动n+1步,然后两个指针同时移动直到p2到达链表末尾,此时p1指向待删除节点的前一个节点,从而完成删除操作。

(3)链表去重(去除重复的数据)
 public ListNode deleteDuplicates(ListNode head) {
        if(head==null||head.next==null){
            return head;
        }
        ListNode p1 = head;
        ListNode p2;
        while((p2 = p1.next)!=null){
            if(p1.val==p2.val){
                p1.next=p2.next;
            }else{
                p1=p1.next;
            }
        }
        return head;
    }

新加入两个指针(P1和P2),P1初始化在头节点,P2节点在P1之后,当程序运行时,两个指针不断比较前后两个节点的值,如果有重复就将重复节点的指针指向该重复节点下面一个节点,直到P2节点指向到空值。

(4)合并链表
public ListNode mergeTwoLists(ListNode p1, ListNode p2) {
        ListNode s=new ListNode(-1,null);
        ListNode p=s;
        while(p1!=null&&p2!=null){
            if(p1.val < p2.val){
               p.next=p1;
               p1=p1.next;
            }else{
                p.next = p2;
                p2 = p2.next;
            }
            p = p.next;
        }
        if(p1!=null){
            p.next=p1;
        }
        if(p2!=null){
            p.next=p2;
        }
        return s.next;
    }

这段代码实现了一个函数`mergeTwoLists`,用于合并两个有序链表`p1`和`p2`。通过创建一个新的头节点`s`,并使用指针`p`来构建新的链表。在遍历过程中,比较`p1`和`p2`当前节点的值,将较小的节点连接到新链表中,并移动相应的指针。当其中一个链表耗尽时,将另一个链表剩余部分直接连接到新链表末尾,最后返回合并后的新链表的头节点。

三、总结

链表是一种由节点组成的线性数据结构,每个节点包含数据和指向下一个节点的指针。常见的链表类型包括单链表、双链表和循环链表。链表支持的操作包括初始化、插入、删除、查找、反转、合并、检测环和排序等。但是在实际运行中,链表往往也会因为不能像数组一样存在索引存在某些问题。

你可能感兴趣的:(JAVA算法详解,java,链表,开发语言,算法,数据结构)