数据结构List浅谈(Java描述)

数据结构List浅谈(java描述)

List(线性表):
List线性表是一种最基本、最简单、同时也是最常用的一种数据结构,一个线性表是具有n个相同类型数据元素的有限序列,其中数据元素之间的关系都是一一对应的。
其特征有:

  1. 集合中必存在唯一的一个“第一元素”
  2. 集合中必存在唯一的一个“最后元素”
  3. 除最后一个元素之外,均有唯一的后继
  4. 除第一个元素之外,均有唯一的前驱

此处所指的 “线性” 只是逻辑上的线性,所以双向链表、循环链表也属于线性表
在逻辑上细分,线性表可分为一般线性表和受限线性表,一般线性表就是诸如顺序表、链表可以自由的增删结点,受限线性表则包括栈,队列结点操作收到限制

在这里插入图片描述

Java中 List接口 实现的方法
List接口实现自Collection接口,该界面用户可精准的控制列表中每个元素的插入位置,用户可通过整数索引访问元素,并搜索列表中的元素。
与集合不同,列表通常允许重复(e1.equals(e2)== true)的元素。

List接口的使用示例:
List 实现杨辉三角

public List<List<Integer>> generate(int numRows) {
    
    
    List<Integer> row = new ArrayList<>();
    List<List<Integer>> col = new ArrayList<>();
        for (int i = 0; i < numRows; i++) {
    
    
        row = new ArrayList<>();
        for (int j = 0; j <= i; j++) {
    
    
            if (j == 0 || j == i) {
    
    
                row.add(1);
            } else {
    
    
                List<Integer> temp = col.get(i - 1);
                row.add(temp.get(j - 1) + temp.get(j));
            }
        }
        col.add(row);

    }
    return col;
}

ArrayList顺序表
顺序表是在计算机内存中以数组的形式保存的线性表,
将表中元素一个接一个的存入一组连续的存储单元中,这种存储结构是顺序结构
顺序表的本质是一个数组

Java中 ArrayList接口 实现自List接口,可调整大小的数组的实现List接口,实现所有可选列表操作,并允许所有元素,包括null 。 除了实现List 接口之外,该类还提供了一些方法来操纵内部使用的存储列表的数组的大小。
每个ArrayList实例都有一个容量 。容量是用于存储列表中的元素的数组的大小,它总是至少与列表大小一样大,当元素添加到ArrayList中容量已满时,其容量会自动增长。

ArrayList的实现 ——

  • 仿写Iterable 接口
package List;
//仿写真实的(java.util.Iterable)接口

public interface Iterable {
    
    
    Iterator iterator();
}
  • 仿写List 接口
public interface List<E> extends Iterable{
    
    
    boolean add(E e);
    void addIndex(int index,E e);
    void clean();
    boolean contains(Object o);
    boolean equals(Object e);
    E get(int index);
    int indexOf(Object o);
    boolean isEmpty();
    E remove(int index);
    boolean remove(Object o);
    E set(int index, E e);
    int size();
}
  • 仿写Iterator 接口
package List;
//仿写真实的(java.util.Iterator)接口

public interface Iterator<E> {
    
    
    boolean hasNext();
    E next();
    void remove();
}
  • 实现一个ArrayList的迭代器
package List;

public class ArrayListIterator implements Iterator {
    
    
    //对一个顺序表迭代,重要在于控制下标
    private MyArrayList arrayList;
    private int index;

    public ArrayListIterator(MyArrayList arrayList) {
    
    
        this.arrayList = arrayList;
        this.index = 0;
    }

    public ArrayListIterator() {
    
    

    }

    @Override
    public boolean hasNext() {
    
    
        return index < arrayList.size();
    }

    @Override
    public Object next() {
    
    
        return arrayList.get(index++);
    }

    @Override
    public void remove() {
    
    
        arrayList.clean();
    }
}
  • 具体实现ArrayList
package List;

import java.util.Arrays;

//仿写真实的(java.util.ArrayList)实现类
public class MyArrayList<E> implements List{
    
    
    private int[] arr;
    private int size;

    public MyArrayList() {
    
    
        this.arr = new int[10];
        this.size = 0;
    }

    @Override
    public boolean add(Object o) {
    
    
        if (!(o instanceof Integer)) {
    
    
            return false;
        }
        if (size == arr.length) {
    
    
                capacity();
        }
        arr[size] = (int)o;
        size++;
        return true;
    }

    @Override
    public void addIndex(int index, Object o) {
    
    
        if(index < 0 || index > size+1){
    
    
            return;
        }
        if (size == arr.length) {
    
    
            capacity();
        }
        for (int i = size; i >= index; i--) {
    
    
            arr[i + 1] = arr[i];
            if (i == index) {
    
    
                arr[index] = (int)o;
                size++;
            }
        }
    }

    private void capacity() {
    
    
        int[] newArr =  new int[2 * arr.length];
        System.arraycopy(arr, 0, newArr, 0, arr.length);
        arr = newArr;
    }

    @Override
    public void clean() {
    
    
        size = 0;
    }

    @Override
    public boolean contains(Object o) {
    
    
        for (int e : arr){
    
    
            if(e == (int)o){
    
    
                return true;
            }
        }
        return false;
    }


    @Override
    public Object get(int index) {
    
    
        if(index < 0 && index > size-1){
    
    
            return null;
        }else{
    
    
            return arr[index];
        }
    }

    @Override
    public int indexOf(Object o) {
    
    
        for (int i = 0 ;i < size;i++) {
    
    
            if(arr[i] == (int)o){
    
    
                return i;
            }
        }
        return -1;
    }

    @Override
    public boolean isEmpty() {
    
    
        return size == 0;
    }

    @Override
    public Object remove(int index) {
    
    
        if(index < 0 || index > size+1){
    
    
            return null;
        }
        int num = arr[index];
        if (size - 1 - index >= 0) System.arraycopy(arr, index + 1, arr, index, size - 1 - index);
        arr[size-1] = 0;
        size--;
        return num;
    }

    @Override
    public boolean remove(Object o) {
    
    
        int i;
        boolean isFind = false;
        for (i = 0; i < size; i++) {
    
    
            if(arr[i] == (int)o){
    
    
                isFind = true;
                break;
            }
        }
        if(isFind) {
    
    
            if (size - 1 - i >= 0) System.arraycopy(arr, i + 1, arr, i, size - 1 - i);
            arr[size - 1] = 0;
            size--;
        }
        return isFind;
    }

    @Override
    public Object set(int index, Object o) {
    
    
        if(index < 0 || index > size+1){
    
    
            return null;
        }
        arr[index] = (int)o;
        return arr[index];
    }

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

    public Iterator iterator() {
    
    
        return new ArrayListIterator(this);
    }

    @Override
    public String toString() {
    
    
        return "MyArrayList{" +
                "arr=" + Arrays.toString(arr) +
                '}';
    }
}

LinkedList(链表)
链表是一种物理存储单元上非连续、非顺序,逻辑上顺序存储的存储结构。使用链表结构可以克服顺序表需要预先知道数据大小的缺点,链表结构可以充分利用计算机内存空间,实现灵活的内存动态管理。链表有很多种不同的类型:单向链表,双向链表以及循环链表,Java中链表以引用的形式存储

Java中的LinkedList 接口实现自List 接口, Deque 接口, Cloneable接口, Serializable接口,双链表实现了List和Deque接口。
实现所有可选列表操作,并允许所有元素(包括null )。所有的操作都能像双向列表一样预期。 索引到列表中的操作将从开始或结束遍历列表,以更接近指定的索引为准。

简单实现链表(单向链表)——

  • 仿写 Iterable接口
package MyLinkedList;

public interface Iterable {
    
    
    Iterator iterator();
}
  • 仿写 Iterator接口
package MyLinkedList;

public interface Iterator {
    
    
    boolean hasNext();
    Integer next();
}
  • 仿写 List接口
package MyLinkedList;

public interface List extends Iterable {
    
    
    void add(Integer e);
    //将指定的元素追加到此列表的末尾
    boolean add(int index, Integer element);
    //在此列表中的指定位置插入指定的元素
    void addFirst(Integer e);
    //在该列表开头插入指定的元素
    void addLast(Integer e);
    //将指定的元素追加到此列表的末尾
    void clear();
    //从列表中删除所有元素
    boolean contains(Object o);
    //如果此列表包含指定的元素,则返回 true
    Integer getFirst();
    //返回此列表中的第一个元素
    Integer getLast();
    //返回此列表中的最后一个元素
    int indexOf(Object o);
    //返回此列表中指定元素的第一次出现的索引,如果此列表不包含元素,则返回-1
    int lastIndexOf(Object o);
    //返回此列表中指定元素的最后一次出现的索引,如果此列表不包含元素,则返回-1
    Integer remove();
    //检索并删除此列表的头(第一个元素)
    Integer remove(int index);
    //删除该列表中指定位置的元素
    boolean remove(Object o);
    //从列表中删除指定元素的第一个出现(如果存在)
    Integer removeFirst();
    //从此列表中删除并返回第一个元素
    Integer set(int index, Integer element);
    //用指定的元素替换此列表中指定位置的元素
    int size();
    //返回此列表中的元素数
    Integer removeLast();
    //从此列表中删除并返回最后一个元素
}
  • 定义LinkedListIterator类,实现Iterator 接口的方法
package MyLinkedList;

public class LinkedListIterator implements Iterator {
    
    
    private SinglyLinkedList list;
    private Node cur;

    public LinkedListIterator(SinglyLinkedList list) {
    
    
        this.list = list;
        this.cur = list.head;
    }

    @Override
    public boolean hasNext() {
    
    
        return cur != null;
    }

    @Override
    public Integer next() {
    
    
        if(cur != null) {
    
    
            cur = cur.next;
            return cur.element;
        }else{
    
    
            return null;
        }
    }
}
  • 定义Node类,存放结点数据
package MyLinkedList;

public class Node {
    
    
    Integer element;
    Node next;

    public Node(Integer val) {
    
    
        this.element = val;
    }

    @Override
    public String toString() {
    
    
        return " " + element + " ";
    }
}
  • 定义SinglyLinkedList类,实现 list 接口的方法
package MyLinkedList;

public class SinglyLinkedList implements List{
    
    
    protected Node head;
    private int size;

    @Override
    public void add(Integer e) {
    
    
        Node node = new Node(e);
        if(head == null){
    
    
            head = node;
        }else{
    
    
            Node cur = head;
            while (cur.next != null){
    
    
                cur = cur.next;
            }
            cur.next = node;
        }
        size++;
    }

    @Override
    public boolean add(int index, Integer element) {
    
    
        if(index < 0 || index > size){
    
    
            return false;
        }
        if(index == 0){
    
    
            addFirst(element);
            return true;
        }
        int count = 0;
        Node node = new Node(element);
        Node cur = head;
        while (count < index-1){
    
    
            cur = cur.next;
            count++;
        }
        Node t = cur.next;
        cur.next = node;
        node.next = t;
        size++;
        return true;
    }

    @Override
    public void addFirst(Integer e) {
    
    
        Node node = new Node(e);
        node.next = head;
        head = node;
        size++;
    }

    @Override
    public void addLast(Integer e) {
    
    
        add(e);
    }

    @Override
    public void clear() {
    
    
        size = 0;
        head = null;
    }

    @Override
    public boolean contains(Object o) {
    
    
        Node cur = head;
        while (cur != null){
    
    
            if(o.equals(cur.element)){
    
    
                return true;
            }
            cur = cur.next;
        }
        return false;
    }

    @Override
    public Integer getFirst() {
    
    
        if(head == null) {
    
    
            return null;
        }else{
    
    
            return head.element;
        }
    }

    @Override
    public Integer getLast() {
    
    
        if(head == null){
    
    
            return null;
        }else{
    
    
            Node cur = head;
            while (cur.next != null){
    
    
                cur = cur.next;
            }
            return cur.element;
        }
    }

    @Override
    public int indexOf(Object o) {
    
    
        Node cur = head;
        int count = 0;
        while (cur != null) {
    
    
            if(o.equals(cur.element)){
    
    
                return count;
            }
            cur = cur.next;
            count++;
        }
            return -1;
    }

    @Override
    public int lastIndexOf(Object o) {
    
    
        int out = -1;
        int count = 0;
        Node cur = head;
        while (cur != null){
    
    
            if(o.equals(cur.element)){
    
    
                out = count;
            }
            cur = cur.next;
            count++;
        }
        return out;
    }

    @Override
    public Integer remove() {
    
    
        if(head == null){
    
    
            return null;
        }
        int out = head.element;
        head = head.next;
        size--;
        return out;
    }

    @Override
    public Integer remove(int index) {
    
    
        if(index < 0 || index > size-1){
    
    
            return null;
        }
        if(index == 0){
    
    
            return remove();
        }
        Node cur = head;
        Node pre = null;
        int count = 0;
        while(count < index){
    
    
            pre = cur;
            cur = cur.next;
            count++;
        }
        int out = cur.next.element;
        pre.next = cur.next;
        size--;
        return out;
    }

    @Override
    public boolean remove(Object o) {
    
    
        Node cur = head;
        Node pre = null;
        int count = 0;
        while(cur != null){
    
    
            if(o.equals(cur.element)){
    
    
                if(pre == null){
    
    
                    remove();
                }else {
    
    
                    pre.next = cur.next;
                }
                return true;
            }
                pre = cur;
                cur = cur.next;
        }
        return false;
    }

    @Override
    public Integer removeFirst() {
    
    
        return remove();
    }

    @Override
    public Integer set(int index, Integer element) {
    
    
        int count = 0;
        Node cur = head;
        while (cur != null){
    
    
            if(count == index){
    
    
                int out = cur.element;
                cur.element = element;
                return out;
            }
            count++;
            cur = cur.next;
        }
        return null;
    }

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

    @Override
    public Integer removeLast() {
    
    
        Node pre = null;
        Node cur = head;
        while (cur.next != null){
    
    
            pre = cur;
            cur = cur.next;
        }if(pre == null){
    
    
            return null;
        }
        pre.next = null;
        return cur.element;
    }

    @Override
    public Iterator iterator() {
    
    
        return new LinkedListIterator(this);
    }

    public void print(){
    
    
        Node cur = head;
        System.out.print("[");
        while (cur != null){
    
    
            System.out.print(cur);
            cur = cur.next;
        }
        System.out.println("]");
    }
}

以上即是本博客对 list 的总结,随着后续学习的深入还会同步的对内容进行补充和修改,如能帮助到各位博友将不胜荣幸,敬请斧正

猜你喜欢

转载自blog.csdn.net/m0_46233999/article/details/109357415