java自定义实现链表LinkedList与顺序表ArrayList

一、ArrayList和LinkedList区别
ArrayList:底层是基于动态数组
根据数组下标访问数组元素的效率最高,向尾部添加元素效率高。
删除数组中元素以及数组中添加数据的效率低,因为要移动数组。(最坏情况下删除第一个元素,要移动第2~n-1个元素都要向前移动一位。

LinkedList:基于链表的动态数组
数据删除添加效率高,只要改变指针指向即可,但是访问数据的平均效率低,需要对链表进行遍历。

总结:对于增加(add)和删除(remove)操作,LinkedList优于ArrayList,因为ArrayList要移动数组。
对于随机访问get和set,ArrayList优于Linked List,因为LinkedList要移动数组。

二、ArrayList类中的主要属性内部类
1.实现ArrayList的相关接口List

public interface List extends Iterable{
    
    
    boolean add(Integer e);
    void add(int index,Integer e);
    //根据下标删除
    Integer remove(int index);
    //删除遇到第一个
    boolean remove(Integer e);
    Integer get(int index);
    Integer set(int index,Integer e);
    int size();
    void clear();
    boolean isEmpty();
    boolean contains(Integer e);
    int indexOf(Integer e);
    int lastIndexOf(Integer e);

2.ArrayList类中的主要属性及构造方法

package List;
import java.lang.reflect.Array;
import java.util.Arrays;

public class ArrayList implements List {
    
    
    private int[] array;
    private int size;
    //无参数构造方法
    public ArrayList(){
    
    
        array=new int[10];
        size=0;
    }
    //有参数构造方法
    public ArrayList(List other){
    
    
        array=new int[other.size()];
        for(int i=0;i<other.size();i++){
    
    
            array[i]=other.get(i);

        }
        size=other.size();

    }

3.**添加(Add)**元素的方法

public boolean add(Integer e) {
    
    
        //扩容
        if(array.length==size){
    
    
            ensureCapacity(array.length*2);
        }
        //相当于尾插
        array[size++]=e;
        return true;
    }

在指定位置index添加e

public void add(int index, Integer e) {
    
    
        //合法性校验
        if(index<0||index>size){
    
    
            throw new IndexOutOfBoundsException("不合法的下标:"+index);
        }
        //扩容2倍
        if(array.length==size){
    
    
            ensureCapacity(array.length*2);
        }
        //循环实现的效果是一样的
//        for(int i=size;i>index;i--){
    
    
//            array[i]=array[i-1];
//        }
        for(int i=size-1;i>=size;i--){
    
    
            array[i+1]=array[i];
        }
        array[index]=e;
        size++;
    }

4.查找相关方法

public Integer get(int index) {
    
    
        if(index<0||index>=size){
    
    
            throw new IndexOutOfBoundsException("下标不合法"+index);
        }
        return array[index];
    }

5.插入相关方法

public Integer set(int index, Integer e) {
    
    
        if(index<0||index>=size){
    
    
            throw new IndexOutOfBoundsException("下标不合法"+index);
        }
        Integer old=array[index];
        array[index]=e;
        return old;

    }

6.删除相关方法

public Integer remove(int index) {
    
    
        if(index<0||index>=size){
    
    
            throw new IndexOutOfBoundsException("下标不合法"+index);
        }
        int e=array[index];
        //从前往后删除
        //[index+1,size-1)的元素搬移到[index,size-2]的位置上
        for(int i=index;i<size;i++){
    
    
            array[i]=array[i+1];
        }
        size--;
        return e;

    }
public boolean remove(Integer e) {
    
    
//        for(int i=0;i<size;i++){
    
    
//            if(array[i]==e){
    
    
//                remove(i);
//                return true;
//            }
//        }
       // return false;
        int index=indexOf(e);
        if(index!=-1){
    
    
            remove(index);
            return true;
        }else{
    
    
            return false;
        }
    }

7.重写ArrayList的toString方法

扫描二维码关注公众号,回复: 12764852 查看本文章
public String toString() {
    
    
        StringBuilder sb=new StringBuilder("[");
        for(int i=0;i<size;i++){
    
    
            sb.append(array[i]);
            if(i!=size-1){
    
    
                sb.append(",");
            }
        }
        sb.append("]");
        return sb.toString();
    }

8.其他方法(扩容)(Iterator)

public void ensureCapacity(int capacity){
    
    
        //检查是否需要搬家
        if(this.array.length>=capacity){
    
    
            return;
        }
        int[] newArray=new int[capacity];
        //从array数组中搬到newArray数组中
        for(int i=0;i<size;i++){
    
    
            newArray[i]=this.array[i];
        }
        //不再关联老的Array
        this.array=newArray;
    }

三、LinkedList类中的主要属性和内部类
1.定义Node节点

public class Node {
    
    
    public Node prev;
    public Node next;
    public Integer element;
    public Node(Integer element){
    
    
        this.element=element;
    }
}
  1. add相关方法
public boolean add(Integer e) {
    
    
        Node newNode=new Node(e);
        if(size==0){
    
    
            this.head=this.last=newNode;
        }else{
    
    
            this.last.next=newNode;
            newNode.prev=this.last;
            this.last=newNode;
        }
        this.size++;
        return true;
    }

在指定位置index添加e:

public void add(int index, Integer e) {
    
    
        if(index<0||index>size){
    
    
            throw new IndexOutOfBoundsException("下标越界"+index);
        }
        if(index==size){
    
    
            //尾插
            add(e);

        }else if(index==0){
    
    
            //头插
            Node newNode=new Node(e);//把值装入结点中
            newNode.next.prev=newNode;
            this.head=newNode;
            size++;
        }else{
    
    
            //其他情况
            //找到Index-1所在的位置,进行结点的插入
            Node prev;
            if(index-1<size/2){
    
    
                prev=head;
                for(int i=0;i<index-1;i++){
    
    
                    prev=prev.next;
                }
            }else{
    
    
                prev=last;
                for(int i=0;i<size-index;i++){
    
    
                    prev=prev.prev;
                }
            }
            //走到这里,prev指向index-1位置的下标
            Node next=prev.next;
            Node newNode=new Node(e);
            newNode.prev=prev;
            newNode.next=next;
            prev.next=newNode;
            next.prev=newNode;
            size++;
        }
    }

3.remove相关方法

 public Integer remove(int index) {
    
    
        if(index<0||index>=size){
    
    
            throw new IndexOutOfBoundsException("下标越界"+index);
        }
        //走到这里,下标一定是>0的
        Integer v;
        if(index==0){
    
    
            v=head.element;
            this.head=this.head.next;
            this.head.prev=null;
            size--;
            if(size==0){
    
    
                last=null;
            }
        }else if(index==size-1){
    
    
            v=last.element;
            this.last=this.last.prev;
            this.last.next=null;
            size--;
            if(size==0){
    
    
                head=null;
            }
        }else{
    
    
            Node prev;
            if(index-1<size/2){
    
    
                prev=head;
                for(int i=0;i<index-1;i++){
    
    
                    prev=prev.next;
                }
            }else {
    
    
                prev=last;
                for(int i=0;i<size-index;i++){
    
    
                    prev=prev.prev;
                }
            }
            Node toRemove=prev.next;
            v=toRemove.element;
            prev.next=toRemove.next;
            toRemove.next.prev=prev;
            size--;
        }
        return v;
    }

4.其他方法

public boolean isEmpty() {
    
    
        return size==0;
    }
public boolean contains(Integer e) {
    
    
        return indexOf(e)!=-1;
    }
public int indexOf(Integer e) {
    
    
        int i=0;
        for(Node cur=head;cur!=null;cur=cur.next,i++){
    
    
            if(cur.element.equals(e)){
    
    
                return i;
            }
        }
        return -1;
    }
public int lastIndexOf(Integer e) {
    
    
        int i=size-1;
        for(Node cur=last;cur!=null;cur=cur.prev,i--){
    
    
            if(cur.element.equals(e)){
    
    
                return i;
            }
        }
        return -1;
    }
 public Iterator iterator() {
    
    
        return new LinkedListIterator(this);
    }

猜你喜欢

转载自blog.csdn.net/m0_46551861/article/details/108721161