【JavaSE学习笔记】chapter07-自定义单向链表

JavaSE学习笔记

学习资源:动力节点java学习

1. 自定义单向链表

package addery.zeus.com.listtest;

/**
 * 单向链表
 */
public class MyLinkedList<E> {
    /**
     * 链表中结点的个数
     */
    private int size;

    /**
     * 链表的头结点
     */
    private Node<E> first;

    public MyLinkedList() {
    }

    /**
     * 默认的添加方式
     * @param data 待添加的数据
     */
    public boolean add(E data) {
        addLast(data);
        return true;
    }

    /**
     * 添加至指定位置
     * @param index 待添加的位置
     * @param data 待添加的数据
     */
    public void add(int index, E data) {
        checkPositionIndex(index);

        if (index == size)
            addLast(data);
        else
            addAppoint(data, node(index), index);
    }

    /**
     * 删除指定索引处的结点,并返回原结点的数据
     * @param index 待删除的索引
     * @return 待删除索引的数据
     */
    public E remove(int index) {
        checkPositionIndex(index);

        Node<E> oldNode = node(index);
        E oldNodeData = oldNode.item;


        if (index == 0) { // 如果删除的是头结点
            first = oldNode.next;
        }else { // 非头结点
            Node<E> oldNodePrev = node(index - 1);
            oldNodePrev.next = oldNode.next;
        }

        oldNode.next = null;
        oldNode.item = null;
        size--;

        return oldNodeData;
    }

    /**
     * 修改指定索引处结点的数据,并返回原始数据
     * @param index 待修改的结点索引
     * @param data 新的结点数据
     * @return 待修改结点的原始数据
     */
    public E set(int index, E data) {
        checkPositionIndex(index);

        Node<E> oldNode = node(index);
        E oldData = oldNode.item;
        oldNode.item = data;

        return oldData;
    }

    /**
     * 获取指定结点处的元素数据
     * @param index 待查找的索引
     * @return 待查找索引的数据
     */
    public E get(int index) {
        checkPositionIndex(index);
        return node(index).item;
    }

    /**
     * 默认添加至末尾
     */
    public void addLast(E data) {
        Node<E> newNode = new Node<>(data, null);

        if (first == null)
            first = newNode;
        else
            node(size - 1).next = newNode;

        size++;
    }

    /**
     * 添加结点至指定位置
     * @param data 待添加的结点数据
     * @param in 目标位置的结点对象
     * @param index 目标位置索引
     */
    void addAppoint(E data, Node<E> in, int index) {
        Node<E> newNode = new Node<>(data, in);

        if (index == 0) { // 如果在头结点处添加结点
            first = newNode;
        } else { // 非头结点处
            Node<E> inPrevNode = node(index - 1);
            inPrevNode.next = newNode;
        }

        size++;
    }

    /**
     * 查找结点,返回结点对象
     * @param index 待查找到结点索引
     * @return 目标节点对象
     */
    Node<E> node(int index) {
        Node<E> x = first;
        for(int i = 0; i < index; i++) {
            x = x.next;
        }
        return x;
    }

    /**
     * 检查下标
     * @param index 下标
     */
    private void checkPositionIndex(int index) {
        if (!isPositionIndex(index))
            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
    }

    /**
     * 下标是否在合理范围内
     * @param index 下标
     * @return 合理true,不合理false
     */
    private boolean isPositionIndex(int index) {
        return index >= 0 && index <= size;
    }

    /**
     * 构造IndexOutOfBoundsException的提示信息
     * @param index 下标
     * @return 提示信息:String
     */
    private String outOfBoundsMsg(int index) {
        return "Index:" + index + ", Size:" + size;
    }

    /**
     * 获取链表中结点的个数
     * @return 结点个数
     */
    public int getSize() {
        return size;
    }

    /**
     * 内部类:单链表的结点
     */
    private static class Node<E> {
        /**
         * 结点数据
         */
        E item;
        /**
         * 下一个结点
         */
        Node<E> next;

        Node(E item, Node<E> next) {
            this.item = item;
            this.next = next;
        }
    }
}

2. JUnit单元测试

package addery.zeus.com.listtest;

import org.junit.jupiter.api.Test;

/**
 * MyLinkedList自定义单链表方法单元测试
 */
public class MyLinkedListMethodTest {
    // add()
    @Test
    public void testAdd() {
        MyLinkedList<String> mll = new MyLinkedList<>();
        mll.add("Zeus");
        mll.add("Stone");
        mll.add("Apple");
        mll.add("pear");
        mll.add("peach");

        mll.add(2,  "Addery");
        //mll.add(10,  "Addery"); // java.lang.IndexOutOfBoundsException: Index:10, Size:6

        for (int i = 0; i < mll.getSize(); i++) {
            System.out.println(mll.get(i));
        }

    }

    // test()
    @Test
    public void testSet() {
        MyLinkedList<String> mll = new MyLinkedList<>();
        mll.add("Zeus");
        mll.add("Stone");
        mll.add("Apple");
        mll.add("pear");
        mll.add("peach");

        String oldData = mll.set(2, "Addery");
        System.out.println(oldData); // Apple

        for (int i = 0; i < mll.getSize(); i++) {
            System.out.println(mll.get(i));
        }

    }

    // remove()
    @Test
    public void testRemove() {
        MyLinkedList<String> mll = new MyLinkedList<>();
        mll.add("Zeus");
        mll.add("Stone");
        mll.add("Apple");
        mll.add("pear");
        mll.add("peach");

        String oldData = mll.remove(1);
        System.out.println(oldData);

        mll.remove(0);
        mll.add("z");

        for (int i = 0; i < mll.getSize(); i++) {
            System.out.println(mll.get(i));
        }
    }

    // get()
    @Test
    public void testGet() {
        MyLinkedList<String> mll = new MyLinkedList<>();
        mll.add("Zeus");
        mll.add("Stone");
        mll.add("Apple");
        mll.add("pear");
        mll.add("peach");

        System.out.println(mll.get(2));
        System.out.println("======");

        for (int i = 0; i < mll.getSize(); i++) {
            System.out.println(mll.get(i));
        }
    }
}
  • 5
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值