双链表的java实现

线性表的接口定义

/**
 * 线性表(列表)的接口定义
 */
public interface MyList {

    /**
     * 新增一个元素
     *
     * @param element 要新增的那个元素
     */
    public void add(Object element);

    /**
     * 删除相同元素
     *
     * @param element 要删除的那个元素
     */
    void delete(Object element);

    /**
     * 根据索引删除元素
     *
     * @param index 要删除元素的索引
     */
    void delete(int index);

    /**
     * 将指定索引位置的元素替换成新元素
     *
     * @param index 被替换元素的索引
     * @param newElement 替换成的新元素
     */
    void update(int index, Object newElement);

    /**
     * 当前列表中是否含有target这个元素
     *
     * @param target 要查找的元素
     * @return 返回是否含有这个元素
     */
    boolean contains(Object target);

    /**
     * 返回指定索引处的元素
     *
     * @param index 要返回元素的索引
     * @return 返回这个元素对象
     */
    Object elementAt(int index);

    /**
     * 查找element所在的索引,如果没有返回-1
     * @param element 要查找的元素
     * @return 返回元素索引
     */
    int indexOf(Object element);
}

 

双链表的节点定义

public class ListNode {
    Object data;
    ListNode pre;
    ListNode next;

    public ListNode(Object data) {
        this.data = data;
    }
}

 

双链表的实现类

public class DoubleLinkList implements MyList {
    //维护两个首尾结点,这两个结点不用来存储data
    private ListNode first = new ListNode(null);
    private ListNode last = new ListNode(null);
    private int size;

    public DoubleLinkList() {
        first.next = last;
        last.pre = first;
    }

    /**
     * 新增一个元素
     *
     * @param element 要新增的那个元素
     */
    @Override
    public void add(Object element) {
        ListNode newNode = new ListNode(element);
        last.pre.next = newNode;
        newNode.next = last;
        newNode.pre = last.pre;
        last.pre = newNode;
        ++size;
    }

    /**
     * 删除相同元素
     *
     * @param element 要删除的那个元素
     */
    @Override
    public void delete(Object element) {
        ListNode p = first.next;

        while (p != last) {
            if (p.data.equals(element)) {
                p.pre.next = p.next;
                p.next.pre = p.pre;
                //加快被删除结点的回收
                p.next = null;
                p.pre = null;
                --size;
                break;
            }
            p = p.next;
        }

    }

    /**
     * 根据索引删除元素
     *
     * @param index 要删除元素的索引
     */
    @Override
    public void delete(int index) {
        if (index < 0 || index >= size) {
            //下标越界,啥也不干
            return;
        }
        //指针指向的节点索引
        int i = 0;
        ListNode p = first.next;

        while (p != last) {
            if (i == index) {
                //删除p结点
                p.pre.next = p.next;
                p.next.pre = p.pre;
                //加快被删除结点的回收
                p.next = null;
                p.pre = null;
                --size;
                break;
            }
            p = p.next;
            ++i;
        }
    }

    /**
     * 将指定索引位置的元素替换成新元素
     *
     * @param index      被替换元素的索引
     * @param newElement 替换成的新元素
     */
    @Override
    public void update(int index, Object newElement) {
        if (index < 0 || index >= size) {
            //下标越界,啥也不干
            return;
        }
        //指针指向的节点索引
        int i = 0;
        ListNode p = first.next;

        while (p != last) {
            if (i == index) {
                p.data = newElement;
                break;
            }
            p = p.next;
            ++i;
        }
    }

    /**
     * 当前列表中是否含有target这个元素
     *
     * @param target 要查找的元素
     * @return 返回是否含有这个元素
     */
    @Override
    public boolean contains(Object target) {
        ListNode p = first.next;

        while (p != last) {
            if (p.data.equals(target)) {
                return true;
            }
            p = p.next;
        }
        return false;
    }

    /**
     * 返回指定索引处的元素
     *
     * @param index 要返回元素的索引
     * @return 返回这个元素对象
     */
    @Override
    public Object elementAt(int index) {
        if (index < 0 || index >= size) {
            //下标越界,啥也不干
            return null;
        }
        //指针指向的节点索引
        int i = 0;
        ListNode p = first.next;

        while (p != last) {
            if (i == index) {
                return p.data;
            }
            p = p.next;
            ++i;
        }
        return null;
    }

    /**
     * 查找element所在的索引,如果没有返回-1
     *
     * @param element 要查找的元素
     * @return 返回元素索引
     */
    @Override
    public int indexOf(Object element) {

        //指针指向的节点索引
        int i = 0;
        ListNode p = first.next;

        while (p != last) {
            if (p.data.equals(element)) {
                return i;
            }
            p = p.next;
            ++i;
        }
        return -1;
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder("[");
        ListNode p = first.next;
        while (p != last) {
            sb.append(p.data);
            if (p.next != last) {
                sb.append(", ");
            }
            p = p.next;
        }
        sb.append("]");
        return sb.toString();
    }
}

 

测试演示

import org.junit.jupiter.api.Test;

class DoubleLinkedListTest {

    @Test
    void delete() {
        DoubleLinkList list = new DoubleLinkList();
        list.add("1");
        list.add("2");
        list.add("3");
        list.add("4");
        list.add("5");

        //删除操作之前输出链表元素
        System.out.println("删除操作之前输出链表元素: " + list);

        list.delete("3");
        //删除元素"3"之后输出链表元素
        System.out.println("删除元素\"3\"之后输出链表元素: " + list);

        //删除下标为0的元素之后输出链表元素
        list.delete(0);
        System.out.println("删除下标为0的元素之后输出链表元素: " + list);
    }
}

 

运行结果截图

在这里插入图片描述

©️2020 CSDN 皮肤主题: 书香水墨 设计师:CSDN官方博客 返回首页