ArrayList(动态数组)、LinkedList(单链表)、DLink(双向链表)的实现

首先来分析一下,这几种存储结构需要实现的共同点,也就是最基础的增删改查。

那么把它们的共性先提取出来,形成一个List接口。然后编写实现时需要继承该接口,重写里面的方法即可。

List接口

这是一个接口,包含这几个操作都需要的基本方法,头部添加元素,尾部添加元素,删除头部元素,删除尾部元素,删除指定元素,更改元素,查找元素,和元素的个数统计。

public interface List<T> {
    //头部添加
    void addHead(T value);
    //尾部添加
    void addTail(T value);
    //头部删除
    void removeHead();
    //尾部删除
    void removeTail();
    //指定元素的删除
    void removeValue(T value);
    //更新元素
    void change(T srcValue, T aimValue);
    //查找元素
    boolean search(T value);
    int size();

}

ArrayList(动态数组)的实现

MyArrayList


import java.util.Arrays;

public class MyArrayList<T extends Comparable<T>> implements List<T> {
    private T[] element;
    private int size;// 标记当前有效数据个数
    private static final int INITSIZE = 10;//开始时的数组大小

    public MyArrayList() {
        element = (T[]) new Comparable[INITSIZE];
        size = 0;
    }

    /*
    比较元素的个数和数组的大小
    如果满就进行1.5倍扩容
    创建一个新的数组(是原数组的1.5倍)并把之前的数组元素复制过来
     */
    private void ensureCapacity() {
        if (element.length == size) { // 已经填满
            int newLength = element.length + (element.length >> 1);
            element = Arrays.copyOf(element, newLength);
        }
    }

    /**
     * 尾部添加操作
     * @param value 需要添加的值
     */
    public void addTail(T value) {
        // 判满扩容操作
        ensureCapacity();
        element[size++] = value;
    }

    /**替换制定元素
     *
     * @param index 旧元素的下标
     * @param value 新元素的值
     */
    public void change(T index, T value) {
        for (int i = 0; i < size; i++) {
            if (element[i].compareTo(index) == 0) {
                element[i] = value;
            }
        }
    }

    /**头部添加
     *
     * @param value 新值
     */
    public void addHead(T value) {
        //1. 判满操作  扩容?
        ensureCapacity();
        //2. 数据移动
//            for(int i = size-1;i>=0;i--){
//                element[i+1] = element[i];
//            }
        System.arraycopy(element, 0, element, 1, size);
        //3. 0下标位置填充value
        element[0] = value;
        //4. size++
        size++;
    }

    /**尾部添加
     *
     * @param value
     */
    public void addtail(T value) {
        ensureCapacity();
        element[size++] = value;
    }

    /**删除value
     *
     * @param value
     */
    public void removeValue(T value) { // 1 2 2 2 3       value:2
        //1. size == 0  判空操作
        if (size == 0) {
            return;
        }
        for (int i = 0; i < size; i++) {
            if (element[i].compareTo(value) == 0) {
                // 数据移动覆盖
                for (int j = i + 1; j < size; j++) {
                    element[j - 1] = element[j];
                }
                size--;
                i--; //如果元素出现移动,i值不增加,
            }
        }
    }

    /**删除头部
     *
     */
    public void removeHead() {
        if (size == 0) {
            return;
        }
//            for(int i = 1;i<size;i++){
//                element[i-1] = element[i];
//            }
        System.arraycopy(element, 1, element, 0, size - 1);
        size--;
    }

    /**删除尾部
     *
     */
    public void removeTail() {
        if (size == 0) {
            return;
        }
        size--;
    }


    /**查找
     *
     * @param value 需要查找的元素
     * @return
     */
    public boolean search(T value) {
        for (int i = 0; i < size; i++) {
            if (element[i].compareTo(value) == 0) {
                return true;
            }
        }
        return false;
    }

    @Override
    public int size() {
        return size;
    }

    //打印
    public void show() {
        System.out.print("动态数组中的元素:");
        for (int i = 0; i < size; i++) {
            System.out.print(element[i] + " ");
        }
        System.out.println();
    }
}


MyArrayListDemo 


import java.util.Scanner;

public class MyArrayListDemo {
    public static void main(String[] args) {
        MyArrayList<Integer> list = new MyArrayList();
        while (true) {
            System.out.println("----请选择以下操作(动态数组):-----");
            System.out.println("1、头部添加");
            System.out.println("2、尾部添加");
            System.out.println("3、头部删除");
            System.out.println("4、尾部删除");
            System.out.println("5、查找值");
            System.out.println("6、删除特定值");
            System.out.println("7、修改值");
            System.out.println("8、查看");
            System.out.println("------------------------");
            Scanner scanner = new Scanner(System.in);
            int i = scanner.nextInt();
            switch (i) {

                case 1: {
                    System.out.println("请输入需要添加的元素");
                    Integer s = scanner.nextInt();
                    list.addHead(s);
                    list.show();
                    continue;
                }
                case 2: {
                    System.out.println("请输入需要添加的元素");
                    Integer s1 = scanner.nextInt();
                    list.addTail(s1);
                    list.show();
                    continue;
                }
                case 3:
                    list.removeHead();
                    list.show();
                    continue;
                case 4:
                    list.removeTail();
                    list.show();
                    continue;
                case 5: {
                    System.out.println("请输入需要查找的元素");
                    Integer s2 = scanner.nextInt();
                    boolean search = list.search(s2);
                    System.out.println(search);
                    continue;
                }
                case 6: {
                    System.out.println("请输入需要删除的元素");
                    Integer s3 = scanner.nextInt();
                    list.removeValue(s3);
                    list.show();
                    continue;
                }
                case 7: {
                    System.out.println("请输入需要修改的下标");
                    Integer s4 = scanner.nextInt();
                    System.out.println("请输入需要修改的新元素");
                    Integer s5 = scanner.nextInt();
                    list.change(s4, s5);
                    list.show();
                    continue;
                }
                case 8:
                    list.show();
                    continue;
                default:
                    System.out.println("输入错误请重新输入!");
                    continue;
            }
        }

    }

}

LinkedList(单链表)

SingleLinkedList

public class SingleLinkedList<E extends Comparable<E>> implements List<E> {
    //单链表
    private Node<E> head;//头
    private Node<E> tail;//尾
    int size;//统计节点个数

    /**
     * 头部添加
     *
     * @param value
     */
    @Override
    public void addHead(E value) {//在头部添加一个节点
        Node<E> newNode = new Node<E>(value);//申请节点
        if (head == null) {//链表里没有任何元素
            head = newNode;
            tail = newNode; //将尾部也更新到新节点中
        } else {
            newNode.next = head;//新的节点的下一个保存原来的头结点
            head = newNode;//更新头结点
        }
        size++;
    }

    /**
     * 尾部添加
     *
     * @param value
     */
    @Override
    public void addTail(E value) {//在尾部添加一个节点
        Node<E> newNode = new Node<E>(value);
        if (size == 0) {//链表里没有任何元素     //if(head == null)
            head = newNode;
            tail = newNode; //将尾部也更新到新节点中
        } else {
            tail.next = newNode;//尾巴节点的下一个保存新节点
            tail = newNode;//更新尾结点
        }
        size++;
    }

    /**
     * 删除头部
     */
    @Override
    public void removeHead() {//删除头结点
        if (size == 0) {
            return;
        }
        head.value = null;//释放空间
        if (size == 1) {//链表只有一个节点时,头部和尾部都为null
            head = null;
            tail = null;
        } else {
            head = head.next;//头部指向头部的下一个
        }
        size--;
    }

    /**
     * 删除尾部
     */
    @Override
    public void removeTail() {//删除尾节点
        Node<E> p = head;
        if (size == 0) {
            return;
        }
        tail.value = null;//释放空间
        if (size == 1) {//链表只有一个节点时,头部和尾部都为null
            head = null;
            tail = null;
        } else {
            for (; p.next != tail; p = p.next) {
            }
            p.next = null;//尾巴的next =null
            tail = p;//更新尾巴
        }
        size--;

    }

    /**
     * 删除指定元素
     *
     * @param value
     */
    @Override
    public void removeValue(E value) {//删除指定元素(可能有多个节点的value值是该元素)
        if (size == 0) {
            return;
        }
        if (tail.value.compareTo(value) == 0) {//如果尾结点等于指定节点,调用删除尾结点方法
            removeTail();
            removeValue(value);
        }
        if (head.value.compareTo(value) == 0) {如果头结点等于指定节点,调用删除尾结点方法
            removeHead();
            removeValue(value);
        } else if (size == 1 && head.value.compareTo(value) != 0) {
            return;
        } else { //size>=2   head.value != value
            for (Node<E> p = head; p.next != null; ) {
                if (p.next.value.compareTo(value) == 0) {
//                    if(p.next == tail){
//                        tail = p;
//                    }
                    p.next.value = null;// 防止内存泄漏
                    p.next = p.next.next;
                    size--;
                } else {
                    p = p.next;
                }

            }

        }

    }

    /**
     * 修改值
     *
     * @param srcValue 原数据
     * @param aimValue 新数据
     */
    @Override
    public void change(E srcValue, E aimValue) {//改变节点的value值
        for (Node<E> p = head; p != null; p = p.next) {
            if (p.value.compareTo(srcValue) == 0) {//遍历链表找到要替换的节点,重新把新的值赋值给value
                p.value = aimValue;
            }
        }
    }

    public Node<E> getHead() {
        return head;
    }

    public Node<E> getTail() {
        return tail;
    }

    public void setHead(Node<E> head) {
        this.head = head;
    }

    public void setTail(Node<E> tail) {
        this.tail = tail;
    }

    /**
     * 搜索节点
     *
     * @param value
     * @return
     */
    @Override
    public boolean search(E value) {//判断元素是否存在
        for (Node<E> p = head; p != null; p = p.next) {
            if (p.value.compareTo(value) == 0) {
                return true;
            }
        }
        return false;
    }

    /**
     * 返回链表节点的个数
     *
     * @return
     */
    @Override
    public int size() {
        return size;
    }//返回size元素个数

    /**
     * 遍历单链表
     */
    public void show() {//展示链表中所有的元素
        System.out.print("单链表中的元素:");
        for (Node<E> p = head; p != null; p = p.next) {
            System.out.print(p.value + "\t");
        }
        System.out.println();
    }


    static class Node<T> {
        private T value;
        private Node<T> next;

        public T getValue() {
            return value;
        }

        public Node<T> getNext() {
            return next;
        }

        public void setNext(Node<T> next) {
            this.next = next;
        }

        public Node(T value) {

            this.value = value;
        }
    }
}

SingleLinkedListDemo  


import java.util.Scanner;

public class SingleLinkedListDemo {
    //单链表
    //头插,尾插,头删,尾删
    public static <T> void main(String[] args) {
        SingleLinkedList<Integer> list = new SingleLinkedList<>();

        while (true) {
            System.out.println("----请选择以下操作(单链表):-----");
            System.out.println("1、头部添加");
            System.out.println("2、尾部添加");
            System.out.println("3、头部删除");
            System.out.println("4、尾部删除");
            System.out.println("5、查找值");
            System.out.println("6、删除特定值");
            System.out.println("7、修改值");
            System.out.println("8、查看");
            System.out.println("------------------------");
            Scanner scanner = new Scanner(System.in);
            int i = scanner.nextInt();
            switch (i) {

                case 1: {
                    System.out.println("请输入需要添加的元素");
                    Integer s = scanner.nextInt();
                    list.addHead(s);
                    list.show();
                    continue;
                }
                case 2: {
                    System.out.println("请输入需要添加的元素");
                    Integer s1 = scanner.nextInt();
                    list.addTail(s1);
                    list.show();
                    continue;
                }
                case 3:
                    list.removeHead();
                    list.show();
                    continue;
                case 4:
                    list.removeTail();
                    list.show();
                    continue;
                case 5: {
                    System.out.println("请输入需要查找的元素");
                    Integer s2 = scanner.nextInt();
                    boolean search = list.search(s2);
                    System.out.println(search);
                    continue;
                }
                case 6: {
                    System.out.println("请输入需要删除的元素");
                    Integer s3 = scanner.nextInt();
                    list.removeValue(s3);
                    list.show();
                    continue;
                }
                case 7: {
                    System.out.println("请输入需要修改的旧元素");
                    Integer s4 = scanner.nextInt();
                    System.out.println("请输入需要修改的新元素");
                    Integer s5 = scanner.nextInt();
                    list.change(s4, s5);
                    list.show();
                    continue;
                }
                case 8:
                    list.show();
                    continue;
                default:
                    System.out.println("输入错误请重新输入!");
                    continue;
            }
        }


 }
}

双向链表的实现

DLink



public class DLink<T extends Comparable<T>> implements List<T> {
    private Node<T> head;
    private Node<T> tail;
    private int size;

    /**
     * 头部添加
     * @param value
     */
    @Override
    public void addHead(T value) {
        Node<T> newNode = new Node<T>(value);
        if(head == null){//链表为空
            head = newNode;
            tail = newNode;

        }else{
            newNode.next = head;
            head.prev = newNode;
            head = newNode;
        }
        size++;
    }

    /**
     * 尾部添加
     * @param value
     */
    @Override
    public void addTail(T value) {
        Node<T> newNode = new Node<T>(value);
        if(tail == null){
            head = newNode;
            tail = newNode;

        }else{
            newNode.prev = tail;
            newNode.next = null;
            tail.next = newNode;
            tail = newNode;
        }
        size++;
    }

    /**
     * 删除头部
     */
    @Override
    public void removeHead() {
        if(size == 0){
            return;
        }
        head.value = null;//释放空间
        if(size == 1){//链表只有一个节点时,头部和尾部都为null
            head = null;
            tail = null;
        }else {
            head = head.next;//头部指向头部的下一个
            head.prev = null;
        }
        size--;

    }

    /**
     * 删除尾部
     */
    @Override
    public void removeTail() {
        Node<T> p = head;
        if(size == 0){
            return;
        }
        tail.value = null;//释放空间
        if(size == 1){//链表只有一个节点时,头部和尾部都为null
            head = null;
            tail = null;
        }else {
            tail.prev.next = null;
            tail = tail.prev;
        }
        size--;

    }

    /**
     * 删除特定元素
     * @param value
     */
    @Override
    public void removeValue(T value) {
        if(size == 0){
            return;
        }
        if(head.value.compareTo(value) == 0){
            removeHead();
            removeValue(value);
        }else if(size == 1 && head.value.compareTo(value) != 0){
            return;
        }
        else{ //size>=2
            for(Node<T> p=head; p!=null;p = p.next){
                if(p.value.compareTo(value) == 0){
                    if(p.next == null){
                        removeTail();
                    }else {
                        p.value = null;// 防止内存泄漏
                        p.prev.next = p.next;
                        p.next.prev = p.prev;
                        size--;
                        p = p.prev;
                    }

                }
            }
        }
    }

    /**
     * 修改元素值
     * @param srcValue
     * @param aimValue
     */
    @Override
    public void change(T srcValue, T aimValue) {
        for(Node<T> p = head;p!= null;p= p.next){
            if(p.value.compareTo(srcValue) == 0){
                p.value = aimValue;
            }
        }
    }


    /**
     * 查找元素
     * @param value
     * @return
     */
    @Override
    public boolean search(T value) {
        for(Node<T> p = head;p != null; p = p.next){
            if(p.value.compareTo(value) == 0){
                return true;
            }

        }        return false;
    }

    /**
     * 链表的长度
     * @return
     */
    @Override
    public int size() {
        return size;
    }

    /**
     * 打印链表
     */
    public  void show(){
        System.out.print("双向链表中的元素:");
        for(Node<T> p = head;p!= null;p= p.next){
            System.out.print(p.value + "\t");
        }
        System.out.println();
    }

    //定义链表中的节点
    static class Node<E>{
        E value;//元素
        Node<E> next;//后一个节点的地址
        Node<E> prev;//前一个节点的地址

        public Node(E value) {
            this.value = value;
        }
    }
}

DLinkDemo 



import java.util.Scanner;

public class DLinkDemo {
    public static <T>void main(String[] args) {
        DLink<Integer> dlink = new DLink<>();
        while (true) {
            System.out.println("----请选择以下操作(动态数组):-----");
            System.out.println("1、头部添加");
            System.out.println("2、尾部添加");
            System.out.println("3、头部删除");
            System.out.println("4、尾部删除");
            System.out.println("5、查找值");
            System.out.println("6、删除特定值");
            System.out.println("7、修改值");
            System.out.println("8、查看");
            System.out.println("------------------------");
            Scanner scanner = new Scanner(System.in);
            int i = scanner.nextInt();
            switch (i) {

                case 1: {
                    System.out.println("请输入需要添加的元素");
                    Integer s = scanner.nextInt();
                    dlink.addHead(s);
                    dlink.show();
                    continue;
                }
                case 2: {
                    System.out.println("请输入需要添加的元素");
                    Integer s1 = scanner.nextInt();
                    dlink.addTail(s1);
                    dlink.show();
                    continue;
                }
                case 3:
                    dlink.removeHead();
                    dlink.show();
                    continue;
                case 4:
                    dlink.removeTail();
                    dlink.show();
                    continue;
                case 5: {
                    System.out.println("请输入需要查找的元素");
                    Integer s2 = scanner.nextInt();
                    boolean search = dlink.search(s2);
                    System.out.println(search);
                    continue;
                }
                case 6: {
                    System.out.println("请输入需要删除的元素");
                    Integer s3 = scanner.nextInt();
                    dlink.removeValue(s3);
                    dlink.show();
                    continue;
                }
                case 7: {
                    System.out.println("请输入需要修改的旧元素");
                    Integer s4 = scanner.nextInt();
                    System.out.println("请输入需要修改的新元素");
                    Integer s5 = scanner.nextInt();
                    dlink.change(s4, s5);
                    dlink.show();
                    continue;
                }
                case 8:
                    dlink.show();
                    continue;
                default:
                    System.out.println("输入错误请重新输入!");
                    continue;
            }
        }

    }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值