Java操作数据结构的单链表

Java各种操作单链表

单链表是一种常用的数据结构,在大学数据结构课程中也学习过,此文章记录一些单链表的简单操作

创建单链表

根据自定义长度创建单链表:

// 创建单链表
public Node createNodeLink(int N) {
    // 定义一个临时节点
    Node preNode = new Node(-1);
    Node head = new Node(1);
    preNode.next = head;
    for (int i = 1; i < N; i++) {
        head.next = new Node(i + 1);
        head = head.next;
    }
    return preNode.next;
}

统计单链表长度

// 计算链表长度
public int getNodesLength(Node head) {
    int len = 0;
    Node tmpNode = head;
    while (tmpNode != null) {
        len++;
        tmpNode = tmpNode.next;
    }
    return len;
}

求单链表倒数第K个节点数据

// 获取链表的倒数第K个节点
public Node getLastKNode(Node head, int K) {
    int len = getNodesLength(head);
    if (K > len) {
        throw new IllegalArgumentException("参数非法,长度太大");
    }
    Node firstNode = head;
    Node secondNode = head;
    while (K > 0) {
        firstNode = firstNode.next;
        K--;
    }
    while (firstNode != null) {
        firstNode = firstNode.next;
        secondNode = secondNode.next;
    }
    return secondNode;
}

链表的反转

// 翻转链表
public Node reverseNode(Node head) {
    Node preNode = null;
    // 链表翻转核心
    while (head != null) {
        /**
         * 创建之后的链表信息为:1->2->3->4...
         */
        // 创建临时节点,第一步将临时节点 tempNode = 2这个节点
        Node tempNode = head.next;
        // 将当前头结点head = 1的下一个节点指向preNode = null
        head.next = preNode;
        // 将preNode节点设置为头结点head = 1
        preNode = head;
        // 将最新的head节点设置成为node = 2这个节点;至此第一个节点head = 1就实现了翻转
        head = tempNode;
    }
    return preNode;
}

不知道head头结点,删除任意中间节点

// 不知道头结点是可以删除任意节点,但是除链表的tail尾结点
public Node removeAnyNode(Node node){
   // 将需要删除的当前节点的后面一个节点向前移一位,用后面一个节点覆盖当前节点数据,同时链接断开,实现删除当前节点
   // 定义临时节点赋值为下一个节点数据
   Node tempNode = node.next;
   // 将当前节点的数据值val变成下一个几点
   node.val = tempNode.val;
   // 当前节点的下一个节点直接指向下下个节点
   node.next = tempNode.next;
   return node;
}

完整代码

import org.junit.jupiter.api.Test;

public class NodeLink {

    public class Node {
        int val;
        Node next;

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

    // 创建单链表
    public Node createNodeLink(int N) {
        // 定义一个临时节点
        Node preNode = new Node(-1);
        Node head = new Node(1);
        preNode.next = head;
        for (int i = 1; i < N; i++) {
            head.next = new Node(i + 1);
            head = head.next;
        }
        return preNode.next;
    }

    // 翻转链表
    public Node reverseNode(Node head) {
        Node preNode = null;
        // TODO 链表翻转核心
        while (head != null) {
            /**
             * 创建之后的链表信息为:1->2->3->4...
             */
            // 创建临时节点,第一步将临时节点 tempNode = 2这个节点
            Node tempNode = head.next;
            // 将当前头结点head = 1的下一个节点指向preNode = null
            head.next = preNode;
            // 将preNode节点设置为头结点head = 1
            preNode = head;
            // 将最新的head节点设置成为node = 2这个节点;至此第一个节点head = 1就实现了翻转
            head = tempNode;
        }
        return preNode;
    }

    // 计算链表长度
    public int getNodesLength(Node head) {
        int len = 0;
        Node tmpNode = head;
        while (tmpNode != null) {
            len++;
            tmpNode = tmpNode.next;
        }
        return len;
    }

    // 获取链表的倒数第K个节点
    public Node getLastKNode(Node head, int K) {
        int len = getNodesLength(head);
        if (K > len) {
            throw new IllegalArgumentException("参数非法,长度太大");
        }
        Node firstNode = head;
        Node secondNode = head;
        while (K > 0) {
            firstNode = firstNode.next;
            K--;
        }
        while (firstNode != null) {
            firstNode = firstNode.next;
            secondNode = secondNode.next;
        }
        return secondNode;
    }

    // 打印翻转之后的链表
    @Test
    public void printReverseNode() {
        Node head = createNodeLink(15);
        Node newHead = reverseNode(head);

        System.out.println("翻转之后的链表:");
        while (newHead != null) {
            if (newHead.next != null) {
                System.out.print(newHead.val + "->");
            } else {
                System.out.print(newHead.val);
            }
            newHead = newHead.next;
        }
    }

    // 打印原始创建的链表数据
    @Test
    public void printRawNode() {
        Node head = createNodeLink(20);
        System.out.println("链表长度len="+getNodesLength(head));
        System.out.println("获取倒数第5的节点:"+getLastKNode(head,5).val);
        System.out.println("创建初始链表:");
        while (head != null) {
            String linkChar = head.next != null ? "->" : "";
            System.out.print(head.val + linkChar);
            head = head.next;
        }
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值