单链表及其反转

本文详细介绍了如何使用Java实现单链表,并提供了添加、删除、更新节点、打印链表、获取有效节点数以及反转链表等操作。通过示例代码展示了如何创建单链表类和测试类,以及如何使用Comparator进行节点的比较和操作。

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


java实现单链表及其反转


提示:以下是本篇文章正文内容,下面案例可供参考

一、单链表是什么?

单链表是一种链式存取的数据结构,其中每个元素视为一个结点,一个结点包含dataNode(数据域,存放实际数据)以及nextNode(指针域,指向下一级结点),其中头结点的dataNode为空,nextNode连接新结点。

二、java实现单链表

1.创建SingleLinkList类

代码如下(示例):

import java.util.Comparator;

/**
 * @author: pikachu
 * @description: 单链表
 */
public class SingleLinkList<E> {
    //初始化头结点
    private final MyNode<E> headNode = new MyNode<E>(null, null);

    public MyNode<E> getHeadNode() {
        return headNode;
    }

    //静态内部类,表示节点类,dataNode为可为自定义类
    private static class MyNode<E> {
        //数据域
        private E dataNode;
        //指针域
        private MyNode nextNode;

        public MyNode(E dataNode, MyNode nextNode) {
            this.dataNode = dataNode;
            this.nextNode = nextNode;
        }
    }

    //添加到尾部
    public void addToRear(E dataNode) {
        MyNode temp = headNode;
        while (temp.nextNode != null) {
            temp = temp.nextNode;
        }
        temp.nextNode = new MyNode(dataNode, null);
    }
    //添加到头部
    public void addToHead(E dataNode){
        MyNode temp = headNode.nextNode;
        headNode.nextNode = new MyNode(dataNode, temp);
    }

    //按照dataNode特定属性(从小到大)插入入链表,比较器用于对该属性进行比较大小
    public void addByAttr(E dataNode, Comparator<E> comparator) {
        MyNode temp = headNode;
        while (temp.nextNode != null) {
            //找到单链表中第一个数据域大于需要插入的节点的数据域dataNode,temp指向插入位置的前一个节点
            if (comparator.compare((E) temp.nextNode.dataNode, dataNode) > 0) {
                break;
            }
            temp = temp.nextNode;
        }
        temp.nextNode = new MyNode(dataNode, temp.nextNode);
    }

    //更新newNode中特定属性与链表中有相同节点的信息
    public boolean updateNode(E newDataNode, Comparator<E> comparator) {
        MyNode temp = headNode;
        while (temp.nextNode != null) {
            if (comparator.compare((E) temp.nextNode.dataNode, newDataNode) == 0) {
                MyNode newNode = new MyNode(newDataNode, temp.nextNode.nextNode);
                temp.nextNode = newNode;
                return true;
            }
            temp = temp.nextNode;
        }
        return false;
    }

    //删除特定节点
    public boolean deleteNode(E delNode, Comparator<E> comparator) {
        MyNode temp = headNode;
        boolean flag = false;
        while (temp.nextNode != null) {
            if (comparator.compare((E) temp.nextNode.dataNode, delNode) == 0) {
                temp.nextNode = temp.nextNode.nextNode;
                flag = true;
            }
            temp = temp.nextNode;
        }
        return flag;
    }

    //打印链表
    public void printLinkList() {
        MyNode temp = headNode;
        if (headNode.nextNode == null) {
            System.out.println("LinkList is empty!");
            return;
        }
        while (temp.nextNode != null) {
            temp = temp.nextNode;
            System.out.println(temp.dataNode);
        }
    }

    //获取有效节点数
    public static int getValidDataNums(MyNode headNode) {
        int i = 0;
        MyNode temp = headNode;
        while (temp.nextNode != null) {
            i++;
            temp = temp.nextNode;
        }
        return i;
    }
    //查找单链表中倒数第k个节点
    public E getInverseKNode(MyNode headNode,int index){
        MyNode<E> temp = headNode;
        int nums = getValidDataNums(headNode);
        if (index> nums||index<=0) {
            return null;
        }
        for (int i = 0; i < nums -index+1; i++) {
            temp = temp.nextNode;
        }
        return temp.dataNode;
    }
    //反转单链表
    public static void inverseLinkList(MyNode headNode){
        MyNode q = headNode.nextNode;
        MyNode p = q.nextNode;
        MyNode t = p;
        //有效节点数<=1
        if (q == null||p==null) {
            return;
        }
       else {
            //临时保存第一个节点,不能在反转前将最后一个节点的nextNode置空
            MyNode lastNode = q;
            while (t.nextNode != null) {
                t = t.nextNode;
                p.nextNode = q;
                q = p;
                p = t;
            }
            //t移动到最后一个节点时,p也指向最后一个节点
            headNode.nextNode = p;
            p.nextNode = q;
            lastNode.nextNode = null;
        }
    }
}

class Hero {
    private int no;
    private String name;

    public Hero(int no, String name) {
        this.no = no;
        this.name = name;
    }

    public int getNo() {
        return no;
    }

    public String getName() {
        return name;
    }

    @Override
    public String toString() {
        return "Hero{" +
                "no=" + no +
                ", name='" + name + '\'' +
                '}';
    }
}

2.编写测试类

代码如下:

class Hero {
    private int no;
    private String name;

    public Hero(int no, String name) {
        this.no = no;
        this.name = name;
    }

    public int getNo() {
        return no;
    }

    public String getName() {
        return name;
    }

    @Override
    public String toString() {
        return "Hero{" +
                "no=" + no +
                ", name='" + name + '\'' +
                '}';
    }
}

class Test3 {
    public static void main(String[] args) {
        Comparator<Hero> heroComparator = Comparator.comparing(Hero::getNo);
        SingleLinkList<Hero> singleLinkList = new SingleLinkList<>();
        System.out.println("getValidDataNums() = " + SingleLinkList.getValidDataNums(singleLinkList.getHeadNode()));

        Hero hero1 = new Hero(1, "No1");
        Hero hero2 = new Hero(2, "No2");
        Hero hero3 = new Hero(3, "No3");
        Hero hero4 = new Hero(4, "No4");

//        singleLinkList.addToRear(hero1);
//        singleLinkList.addToRear(hero2);
//        singleLinkList.addToRear(hero3);

        System.out.println("compare(hero1, hero2) = " + heroComparator.compare(hero1, hero2));

        singleLinkList.addByAttr(hero1, heroComparator);
        singleLinkList.addByAttr(hero2, heroComparator);
        singleLinkList.addByAttr(hero3, heroComparator);
        singleLinkList.addByAttr(hero4, heroComparator);

        System.out.println("反转单链表:");
        SingleLinkList.inverseLinkList(singleLinkList.getHeadNode());
        singleLinkList.printLinkList();

        System.out.println("插入新节点");
        singleLinkList.addByAttr(hero4, heroComparator);
        singleLinkList.printLinkList();
        System.out.println("getValidDataNums() = " + SingleLinkList.getValidDataNums(singleLinkList.getHeadNode()));


        System.out.println("更新节点");
        System.out.println("updateNode: " + singleLinkList.updateNode(new Hero(1, "newNo3"), heroComparator));
        singleLinkList.printLinkList();

        System.out.println("获取倒数第k个节点:");
        System.out.println("getInverseKNode(k) = " + singleLinkList.getInverseKNode(singleLinkList.getHeadNode(), 5));

        System.out.println("删除节点:");
        System.out.println("deleteNode: " + singleLinkList.deleteNode(new Hero(6, ""), heroComparator));
        System.out.println("deleteNode: " + singleLinkList.deleteNode(new Hero(1, ""), heroComparator));
        System.out.println("deleteNode: " + singleLinkList.deleteNode(new Hero(2, ""), heroComparator));
        System.out.println("deleteNode: " + singleLinkList.deleteNode(new Hero(3, ""), heroComparator));
        System.out.println("deleteNode: " + singleLinkList.deleteNode(new Hero(4, ""), heroComparator));
        singleLinkList.printLinkList();
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值