Java基础系列6——链表LinkedList

链表:

  • 链表 与 数组区别:
    • 数组:长度固定 / 连续的空间 / 下标操作快
    • 链表:长度可变 / 不连续 / 增加数据快/删除数据快/遍历慢/查找数据慢
      • 结构变化更灵活

节点:

  • 一个数据存储域
  • 指向其他节点的 引用/指针

首先,设置一个节点类,每个节点拥有自身内容和指向下一个节点的指针两个属性,并增加它们的获取和判断方法。

class Node<E>{
    private Object e;
    private Node next;

    public Node(E e, Node next){
        this.e = e;
        this.next = next;
    }

    public boolean next(){
        return next != null;
    }

    public E getValue(){
        return (E) e;
    }

    public Node getNext() {
        return next;
    }

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

接下来,就可以开始写链表类。先把基本的属性和构造方法写好。

public class MyLinkedList<E> implements List<E>{
    Node<E> root;
    int length;
    int size;
//    Node<E> last;
    public MyLinkedList(){
    }

值得一提的是,我这里写了一个接口List用来规范这些链表。

public interface List<E>{

    int size();
    
    void add(E e);

    void addAll(List<E> otherList);

    E get(int index);

    boolean contains(E e);

    boolean containsAll(E e);

    E remove(int index);

    void remove(E e);

    void removeAll(List<E> eList);

    void set(int index, E e);

    Object[] toArray();
}

因此,MyLinkedList类里就改写这些方法。

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

    @Override
    public void add(E e){
        if(root == null){
            root = new Node<E> (e, null);
            length++;
            size++;
            return;
        }
        // 尾插法
        // 顺着链表 遍历找到为空的节点 实例化一个节点对象 存储进去
        Node<E> tempNode = root;
        while(tempNode.next ()){
            tempNode = tempNode.getNext ();
        }
        Node<E> next = tempNode.getNext ();
        next = new Node<> (e, null);
        tempNode.setNext (next);
        length++;
        size++;
    }


    @Override
    public void addAll(List<E> otherList){
        // 类型判断
        if(otherList instanceof MyLinkedList<E>){
            MyLinkedList<E> newList=(MyLinkedList<E>)otherList;
            // 节点相连
            Node<E> pnode=newList.root;
            for(int i = 0; i < newList.size; i++){
                add(pnode.getValue());
                if(pnode.next()){
                    pnode=pnode.getNext();
                }
            }

        }else{
            MyArrayList<E> newList=(MyArrayList<E>)otherList;
            for(int i=0;i<newList.getIndex();i++){
                add((E) newList.getfi(i));
            }
//            将数组中元素一个添加过来
        }
    }

    @Override
    public E get(int index) {
        return null;
    }

    @Override
    public boolean contains(E e){
        Object pe=root.getValue();
        Node<E> pnode=root;
        if (pe.equals(e)){return true;};
        while (pnode.next()){
            if(!pe.equals(e)){
                pnode=pnode.getNext();
            }else {
                return true;
            }
        }
        if (pe.equals(e)){return true;};
        return false;
    }

    @Override
    public boolean containsAll(E e){
        return false;
    }

    @Override
    public E remove(int index){
        return null;
    }

    @Override
    public void remove(E e){
        Node<E> pnode=root;
        if(pnode.getValue().equals(e)){
            root = pnode.getNext();
        }
        while (pnode.getNext().next()){//如果当前节点存在下两个
            if(pnode.getNext().getValue().equals(e)){//下一个节点等于e
                pnode.setNext(pnode.getNext().getNext());//则当前节点直接连接下下个节点
                length--;
                size--;
            }else{//下一个节点不等于e
                pnode=pnode.getNext();//则向后遍历
            }
        }
        if (pnode.next()){//当前节点后面只剩一个
        if (pnode.getNext().getValue().equals(e)){//如果后面那个节点等于e
            pnode.setNext(null);
            length--;
            size--;
        }
        }else {//如果当前链表只有这一个节点
            root=null;
            length=0;
            size=0;
        }
    }

    @Override
    public void removeAll(List<E> eList){
        if(eList instanceof MyLinkedList<E>){
            MyLinkedList<E> newList=(MyLinkedList<E>)eList;
            // 节点相连
            Node<E> pnode=newList.root;
            for(int i = 0; i < newList.size; i++){
                remove(pnode.getValue());
                if(pnode.next()){
                    pnode=pnode.getNext();
                }
            }
        }else {
            MyArrayList<E> newList = (MyArrayList<E>) eList;
            for (int i = 0; i < newList.getIndex(); i++) {
                remove((E) newList.getValues()[i]);
            }
        }
    }

    // 插入
    @Override
    public void set(int index, E e){
        if(index>size-1){
            System.out.println("输入超出链表长度");
            return;
        }
        Node<E> pnode=root;
        Node<E> newnode=new Node<E>(e,null);
        for(int i = 0; i < size; i++){
            pnode=pnode.getNext();
        }
        //到达index-1位置节点
        if(pnode.next()){
            newnode.setNext(pnode.getNext());
        }
        pnode.setNext(newnode);
    }

    public Object[] toArray(){
        Node<E> pnode=root;
        Object[] arr = new Object[size];
        for(int i = 0; i < size-1; i++){
            arr[i]=pnode.getValue();
            pnode=pnode.getNext();
        }
        arr[size-1]=pnode.getValue();
        return arr;
    }

    @Override
    public String toString(){
        Node<E> pnode=root;
        String s="";
        for(int i = 0; i < size-1; i++){
            s+=pnode.getValue().toString();
            pnode=pnode.getNext();
        }
        s+=pnode.getValue().toString();
        return s;
    }

最后,对这些方法进行测试。

public static void main(String[] args) {
        MyLinkedList<Integer> list1=new MyLinkedList<>();
        MyLinkedList<Integer> list2=new MyLinkedList<>();
        MyLinkedList<Integer> list3=new MyLinkedList<>();
        list1.add(new Integer(1));
        list1.add(new Integer(2));
        list1.add(new Integer(3));
        list2.add(new Integer(1));
        list2.add(new Integer(2));
        list2.add(new Integer(3));
        list3.add(new Integer(4));
        list3.add(new Integer(5));
        list3.add(new Integer(6));
        System.out.println(list1.toString());
        System.out.println(list1.equals(list2));
        System.out.println(list1.equals(list3));
        list3.addAll(list1);
        list3.addAll(list2);
        System.out.println(list3.contains(new Integer(1)));
        list3.remove(new Integer(1));
        System.out.println(list3.toString());
        list3.removeAll(list1);
        System.out.println(list3.toString());
    }

测试结果:

123
false
false
false
4562323
456

因此这个复现还是不错滴

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值