【数据结构与算法】链表1:单向链表(Java实现)


【数据结构与算法】链表1:单向链表(Java实现)

前言

链表是重要的数据结构之一,这里主要使用Java来实现单向链表中的各项基本功能,以达到学习单向链表的目的。

程序代码

为了实现单向链表,这里主要使用到了下面的三个类:

  • Node类:用来定义数据节点
  • SingleLinkList类:单向链表类
  • TestSingleLinkList类:用来测试单向链表的功能
Node类

程序代码如下:

package chapter03_SingleLinkList;
/*
 * 单向链接的节点类型
 * 该节点用来保存学生的成绩信息:
 * number:学号
 * name:姓名
 * score:成绩
 * next:下一个学生的成绩信息
 * 其中,number是唯一的,不允许重复
 */
public class Node {
    String number;
    String name;
    Double score;
    Node next;

    public Node(String number, String name, Double score){
        this.number = number;
        this.name = name;
        this.score = score;
    }
}
SingleLinkList类

程序代码如下:

package chapter03_SingleLinkList;
/*
 * 单向链表
 * 主要用来保存单向链表的列表首,即提供链表的入口,否则将无法对链表进行操作
 * 同时提供一些单向链表的操作方法:
 * public boolean isEmpty()
 * public boolean isExist(Node node)
 * public void displayLinkList()
 * public boolean insertNode(Node node)
 * public boolean insertNode(Node sourceNode, Node node)
 * public boolean deleteNode(Node node)
 * 
 */
public class SingleLinkList {
    public Node firstNode;  //链表的第一个节点
    public Node lastNode;   //链表的最后一个节点

    /*
     * 判断当前的链表是否为空
     */
    public boolean isEmpty(){
        return firstNode == null;
    }

    /*
     * 判断节点是否存在(以学号作为唯一标识)
     */
    public boolean isExist(Node node){
        //如果链表为空,直接返回fasle
        if(this.isEmpty())
            return false;
        Node currentNode = firstNode;
        while (currentNode != null) {
            if(currentNode.number == node.number)
                return true;
            currentNode = currentNode.next;
        }
        //如果上面循环没有执行return语句,说明不存在,返回false
        return false;
    }

    /*
     * 输出链表的内容
     */
    public void displayLinkList(){
        Node currentNode = firstNode;
        while (currentNode != null) {
            System.out.println("学号:" + currentNode.number + " 姓名:" + currentNode.name + " 成绩:" + currentNode.score);
            currentNode = currentNode.next;
        }
    }

    /*
     * 向链表中插入节点(默认为在链表最后插入节点)
     */
    public boolean insertNode(Node node){
        //如果节点已经存在,插入节点失败
        if(this.isExist(node)){
            System.err.println("节点已经存在,插入节点失败!");
            return false;
        } else {
            //节点不存在时才做插入节点的操作
            if(this.isEmpty()){
                //如果当前链表为空,则第一个节点和最后一个节点都为当前节点
                firstNode = node;
                lastNode = node;
            } else {
                //如果当前链表不为空,设置链表最后一个节点的下一个节点为node
                //同时最后一个节点设置为node,从而完成节点的插入操作
                lastNode.next = node;
                lastNode = node;
            }
            return true;
        }
    }

    /*
     * 向链表中插入节点(在链表某个节点位置插入节点)
     */
    public boolean insertNode(Node sourceNode, Node node){
        //如果节点已经存在或者sourceNode不存在,插入节点失败
        if(this.isExist(node) == true || this.isExist(sourceNode) == false){
            System.err.println("节点已经存在或需要插入的节点位置不存在,插入节点失败!");
            return false;
        } else {
            //节点不存在时才做插入节点的操作
            if(this.isEmpty()){
                //如果当前链表为空,则第一个节点和最后一个节点都为当前节点
                firstNode = node;
                lastNode = node;
            } else {
                if(sourceNode.number == firstNode.number){
                    //如果在开头插入节点
                    node.next = firstNode;
                    firstNode = node;
                } else if (sourceNode.number == lastNode.number) {
                    //如果在结尾插入节点
                    lastNode.next = node;
                    lastNode = node;
                } else {
                    //如果在中间插入节点
                    //currentNode--nextNode--nextNextNode
                    //==>currentNode--node--nextNode--nextNextNode
                    Node currentNode = firstNode;
                    Node nextNode = firstNode.next;
                    while(nextNode.number != sourceNode.number){
                        currentNode = nextNode;
                        nextNode = nextNode.next;
                    }
                    currentNode.next = node;
                    node.next = nextNode;
                }
            }
            return true;
        }
    }

    /*
     * 删除链表中的节点
     */
    public boolean deleteNode(Node node){
        //如果节点不存在,删除节点失败
        if(this.isExist(node) == false){
            System.err.println("节点不存在,删除节点失败!");
            return false;
        }
        if(node.number == firstNode.number){
            //如果删除的是第一个节点
            firstNode = firstNode.next;
        } else if (node.number == lastNode.number) {
            //如果删除的是最后一个节点
            Node currentNode = firstNode;
            while(currentNode.next != lastNode){
                currentNode = currentNode.next;
            }
            currentNode.next = null;
            lastNode = currentNode;
        } else {
            //如果删除的是中间节点
            //currentNode--nextNode--nextNextNode
            //==>currentNode--nextNextNode
            Node currentNode = firstNode;
            Node nextNode = firstNode.next;
            while(nextNode.number != node.number){
                currentNode = nextNode;
                nextNode = nextNode.next;
            }
            currentNode.next = nextNode.next;
        }
        node.next = null;
        return true;

    }
}
TestSingleLinkList类

基本程序代码如下:

package chapter03_SingleLinkList;
/*
 * 单向链表测试
 */
public class TestSingleLinkList {
    public static void main(String[] args) throws InterruptedException {
        SingleLinkList singleLinkList = new SingleLinkList();

        Node node1 = new Node("3114006441", "叶泳豪", (double) 95);
        Node node2 = new Node("3214006442", "陈琳", 90.0);
        Node node3 = new Node("3214006443", "李洁玲", 90.0);
        Node node4 = new Node("3214006444", "刘映彤", 90.0);
        Node node5 = new Node("3214006445", "陈舒敏", 90.0);
        Node node6 = new Node("3214006446", "孔冰艳", 90.0);
        Node node7 = new Node("3214006447", "余瑞虹", 90.0);
        Node node8 = new Node("3214006448", "周桑霓", 90.0);
        Node node9 = new Node("3214006449", "何嘉颖", 90.0);

        singleLinkList.insertNode(node1);
        singleLinkList.insertNode(node2);
        singleLinkList.insertNode(node3);
        singleLinkList.insertNode(node4);
        singleLinkList.insertNode(node5);
        singleLinkList.insertNode(node6);
        singleLinkList.insertNode(node7);
        singleLinkList.insertNode(node8);
        singleLinkList.insertNode(node9);

        System.out.println("原始链表:");
        singleLinkList.displayLinkList();

    }
}

可以看到上面的代码只是向链表中添加了部分节点,因为在简单测试的情况下,可以自行修改代码来进行节点的各项内容测试。

测试
插入节点

直接利用上面提供的代码,执行结果如下:

原始链表:
学号:3114006441 姓名:叶泳豪 成绩:95.0
学号:3214006442 姓名:陈琳 成绩:90.0
学号:3214006443 姓名:李洁玲 成绩:90.0
学号:3214006444 姓名:刘映彤 成绩:90.0
学号:3214006445 姓名:陈舒敏 成绩:90.0
学号:3214006446 姓名:孔冰艳 成绩:90.0
学号:3214006447 姓名:余瑞虹 成绩:90.0
学号:3214006448 姓名:周桑霓 成绩:90.0
学号:3214006449 姓名:何嘉颖 成绩:90.0

至于在开头、结尾和中间插入节点的功能,可自行测试。

删除节点

在上面的基础上,添加如下代码:

//分别删除首节点、尾节点和中间节点
singleLinkList.deleteNode(node1);
singleLinkList.deleteNode(node9);
singleLinkList.deleteNode(node5);
//输出删除节点后的链表
System.out.println();
System.out.println("删除节点后的链表:");
singleLinkList.displayLinkList();

执行结果如下:

原始链表:
学号:3114006441 姓名:叶泳豪 成绩:95.0
学号:3214006442 姓名:陈琳 成绩:90.0
学号:3214006443 姓名:李洁玲 成绩:90.0
学号:3214006444 姓名:刘映彤 成绩:90.0
学号:3214006445 姓名:陈舒敏 成绩:90.0
学号:3214006446 姓名:孔冰艳 成绩:90.0
学号:3214006447 姓名:余瑞虹 成绩:90.0
学号:3214006448 姓名:周桑霓 成绩:90.0
学号:3214006449 姓名:何嘉颖 成绩:90.0

删除节点后的链表:
学号:3214006442 姓名:陈琳 成绩:90.0
学号:3214006443 姓名:李洁玲 成绩:90.0
学号:3214006444 姓名:刘映彤 成绩:90.0
学号:3214006446 姓名:孔冰艳 成绩:90.0
学号:3214006447 姓名:余瑞虹 成绩:90.0
学号:3214006448 姓名:周桑霓 成绩:90.0
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值