Java中单链表的实现及一些简单链表题运行案例

Java中单链表的实现及一些简单链表题运行案例

1.链表类和节点内部类的创建
2.插入节点
3.删除节点
4.获取头节点
5.获取链表长度
6.判断链表是否为空
7.判断链表中某数据是否存在
8.根据索引获取元素
9.用新数据替换指定位置的的数据
10.清空链表
11.获取链表中第k个节点
12.判断两个链表是否相交
13.获取两个相交链表的第一个公共节点
14.判断链表是否有环
15.获取环链表的长度
16.获取环链表的入口节点值
17.方法测试(过程包括创建链表、构造相交链表、环链表等)

public class SingleLinkedList {
    //记录节点个数
    private int size;
    //头节点
    private Node head;
    class Node{
       public int val;
        public Node next;
        public Node(int x){
            this.val=x;
        }
    }
    //在尾部插入节点
    public void insertTail(int val){
        Node cur=new Node(val);
        if(head==null)head=cur;
        Node temp=head;
        while(temp.next!=null){
            temp=temp.next;
        }
        temp.next=cur;
        cur.next=null;
        this.size++;
    }
    //删除某个节点
    public Node deleteNode(Node head, int val) {
        Node node = head;
        //如果第一个节点就是要删除的节点,就直接返回下一节点
        if ( node.val == val ) return head.next;
        while (node != null && node.next != null) {
            //从第二个节点开始判断
            if ( node.next.val == val ) {
                node.next = node.next.next;
                break;
            }
            node= node.next;
        }
        size--;
        return head;

        //从第一个节点开始判断
      /* Node node=new Node(0);
       node.next=head;
       Node cur=node;
       while(cur!=null&&cur.next!=null)
       {
           //从第二个节点开始判断
           if(cur.next.val==val)
           {
              cur.next=cur.next.next;
               break;
           }
          cur=cur.next;
       }
       return node.next;*/

    }
    //获取节点个数
    public int getSize() {
        return size;
    }
    //获取链表的头节点
    public Node getHead() {
        return head;
    }
    //判断链表是否为空
    public boolean isEmpty(){
        if(this.size==0){
            return true;
        }else {
            return false;
        }
    }
    //判断链表中某一数据是否存在
    public boolean contains(int x){
        //获取链表的头节点
            Node head=getHead();
            while(head!=null&&head.next!=null){
                if(head.val==x)return true;
                head=head.next;
            }
        return false;
    }
    //根据索引获取元素
    public int get(int index){
        if(index>size-1){
            System.out.println("超出链表边缘");
            return -1;
        }
        else{
            Node head=getHead();
           for(int i=0;i<size;i++){
               if(i==index)return head.val;
                head=head.next;
            }
        }
        return 0;
    }
    //用新数据替换指定位置的的数据
    public void replace(int val,int index){
        if(index>size-1){
            System.out.println("超出链表边缘");
            return ;
        }else{
            Node head=getHead();
            for(int i=0;i<size;i++){
                if(i==index) head.val=val;
                head=head.next;
            }
        }

    }
    //清空链表
    public void clear(){
        this.head=null;
        this.size=0;
    }
    //获取链表中第k个节点
    public Node getKthFromEnd(Node head,int k){
        Node fast=new Node(0);
        fast=head;
        while(fast!=null){
            if(k==0) {
                head = head.next;
            }
            else{
                k--;
            }
            fast=fast.next;
        }
        return head;
    }
    //反转链表
    public Node reverseList(Node head){
        if(head==null)return null;
        Node cur=null;
        while(head!=null){
            Node temp=head.next;
            head.next=cur;
            cur=head;
            head=temp;
        }
        return cur;
    }
    //判断两个链表是否相交
    public boolean isIntersectionNode(Node n1,Node n2){
        Node node1=n1,node2=n2;
        while (node1!=node2){
            node1=node1==null?n2:node1.next;
            node2=node2==null?n1:node2.next;
        }
        if(node1==null)return false;
        else
            return true;
    }
    //获取两个相交链表的第一个公共节点
    public static Node getIntersectionNode(Node n1,Node n2){
        Node node1=n1,node2=n2;
        while (node1!=node2){
            node1=node1==null?n2:node1.next;
            node2=node2==null?n1:node2.next;
        }
        return node1;
    }
    //构建一个有环的链表
   /* public Node loopList(){
        Node cur=head;
        while (cur!=null){
            cur=cur.next;
        }
        cur.next=head.next;
        return head;
    }*/
    //判断链表是否有环
    public   boolean isLoopList(Node head) {
        Node slowPointer, fastPointer;
        //使用快慢指针,慢指针每次向前一步,快指针每次两步
        slowPointer = fastPointer = head;
        while (fastPointer != null && fastPointer.next != null) {
            slowPointer = slowPointer.next;
            fastPointer = fastPointer.next.next;
            //两指针相遇则有环
            if ( slowPointer == fastPointer ) {
                return true;
            }
        }
        return false;
    }
    //获取环链表的长度,环的长度是第一次相遇时,慢指针走的路程(主要是因为从头节点到环入口点的距离等于相遇节点到尾部节点的距离)
    public   int loopListLen(Node head) {
        Node slowPointer, fastPointer;
        int len=0;
        //使用快慢指针,慢指针每次向前一步,快指针每次两步
        slowPointer = fastPointer = head;
        while (fastPointer != null && fastPointer.next != null) {
            slowPointer = slowPointer.next;
            fastPointer = fastPointer.next.next;
            len++;
            //两指针相遇则有环
            if ( slowPointer == fastPointer ) {
                return len;
            }
        }
        //如果不为环,返回-1
        return -1;
    }
    //获取入口节点的值
    public   int getLoopNode(Node head) {
        Node slowPointer, fastPointer;
        //使用快慢指针,慢指针每次向前一步,快指针每次两步
        slowPointer = fastPointer = head;
        while (fastPointer != null && fastPointer.next != null) {
            slowPointer = slowPointer.next;
            fastPointer = fastPointer.next.next;
            //两指针相遇则有环
            if ( slowPointer == fastPointer ) {
                break;
            }
        }
        slowPointer=head;
        while(fastPointer != null && fastPointer.next != null){
            slowPointer = slowPointer.next;
            fastPointer = fastPointer.next;
            if ( slowPointer == fastPointer ) {
                return slowPointer.val;
            }
        }
        return -1;
    }
}
class TestDemo{
    public static void main(String[] args){
        //新建一个链表
        SingleLinkedList lk=new SingleLinkedList();
        //在链表中插入值
        lk.insertTail(1);
        lk.insertTail(2);
        lk.insertTail(3);
        lk.insertTail(4);
        lk.insertTail(5);
        //判断两个链表是否相交
        //测试getIntersectionNode方法
        //构造两个相交链表
        SingleLinkedList lk1=new SingleLinkedList();
        //测试是否为环链表,获取环长度
        lk1.insertTail(6);
        lk1.insertTail(7);
        lk1.insertTail(8);
        SingleLinkedList.Node h=lk1.getHead( );
        SingleLinkedList.Node cur=h;
        //构建一个环长度为2的入口节点为第二个节点值7的环链表
        while (cur.next!=null){
            cur=cur.next;
        }
        cur.next=h.next;
        System.out.println("是否为环链表:"+lk1.isLoopList(h));
        System.out.println("环长度:"+lk1.loopListLen(h));
        System.out.println("环入口节点:"+lk1.getLoopNode(h));
        //构建两个相交链表
        SingleLinkedList lk2=new SingleLinkedList();
        SingleLinkedList lk3=new SingleLinkedList();
        SingleLinkedList lk4=new SingleLinkedList();
        lk2.insertTail(1);
        lk2.insertTail(2);
        lk2.insertTail(3);
        lk3.insertTail(3);
        lk3.insertTail(2);
        lk3.insertTail(1);
        lk4.insertTail(5);
        lk4.insertTail(6);
        lk4.insertTail(7);
        SingleLinkedList.Node h1=lk2.getHead();
        SingleLinkedList.Node h2=lk3.getHead();
        SingleLinkedList.Node h3=lk4.getHead();
        SingleLinkedList.Node temp1=h1;
        SingleLinkedList.Node temp2=h2;
       while (temp1.next!=null){
            temp1=temp1.next;
        }
        temp1.next=h3;
        while (temp2.next!=null){
            temp2=temp2.next;
        }
        temp2.next=h3;
        SingleLinkedList.Node firstNode= SingleLinkedList.getIntersectionNode(h1,h2);
        System.out.println("相交链表第一个相交节点:"+firstNode.val);
        //删除一个元素
        SingleLinkedList.Node head =lk.deleteNode(lk.getHead( ),2);
        //获取节点个数
        System.out.println("节点个数"+": "+lk.getSize());
           // SingleLinkedList.Node head = lk.getHead( );
            while(head!=null){
                System.out.println(head.val);
                head=head.next;
           }
        //反转链表
         /*   SingleLinkedList.Node reverseHead = lk.reverseList(lk.getHead( ));
            while(reverseHead!=null){
                System.out.print(reverseHead.val+" ");
                reverseHead=reverseHead.next;
            }*/
        System.out.println();
        //判断链表是否为空
        System.out.println(lk.isEmpty());
        //判断链表中是否包含某数据
        System.out.println(lk.contains(6));
        System.out.println(lk.contains(1));
        //获取某个节点的数据,使用时需要注释掉反转链表的部分,否则会报错空指针异常
         System.out.println(lk.get(3));
        //用新数据替换指定位置的的数据
        lk.replace(8,3);
       System.out.println(lk.get(3));
        //获取倒数第k个节点
        SingleLinkedList.Node kthHead=lk.getKthFromEnd(lk.getHead(),2);
        while(kthHead!=null){
            System.out.print(kthHead.val+" ");
            kthHead=kthHead.next;
        }
        System.out.println();
        //清空链表
        lk.clear();
        //清空链表后判断链表是否为空
        System. out.println(lk.isEmpty());
    }







}

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java,单向链表是一种常见的数据结构,它由一系列节点组成,每个节点包含数据和指向下一个节点的指针。单向链表的特点是只能从头节点开始遍历到尾节点,不能反向遍历。 下面是一个简单Java实现单向链表的例子: ```java public class Node { int data; // 节点数据 Node next; // 指向下一个节点的指针 public Node(int data) { this.data = data; this.next = null; } } public class LinkedList { Node head; // 链表头节点 public LinkedList() { this.head = null; } // 在链表尾部添加节点 public void add(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 boolean contains(int data) { Node current = head; while (current != null) { if (current.data == data) { return true; } current = current.next; } return false; } // 删除链表第一个出现的指定节点 public void remove(int data) { if (head == null) { return; } if (head.data == data) { head = head.next; return; } Node current = head; while (current.next != null) { if (current.next.data == data) { current.next = current.next.next; return; } current = current.next; } } // 获取链表的节点数 public int size() { int count = 0; Node current = head; while (current != null) { count++; current = current.next; } return count; } } ``` 在上面的代码,Node表示链表节点,LinkedList表示单向链表。它包含了添加、查找、删除和获取节点数等常见操作。你可以根据自己的实际需求来对链表进行操作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值