zoukankan      html  css  js  c++  java
  • 自定义(单链表)集合类

    类的结构

    接口:MyList

     1 package day2_19.inter;
     2 
     3 /**
     4  * 将arryList 和 linkedList 共性的方法进行抽取 --->保证体系的完整性
     5  *
     6  * @Author Tianhao
     7  * @create 2021-02-19-17:26
     8  */
     9 
    10 public interface MyList<E>{
    11 
    12 
    13     public int size();
    14 
    15 
    16     public boolean isEmpty();
    17 
    18 
    19     public boolean contains(Object o);
    20 
    21 
    22     public boolean add(E e);
    23 
    24     public void add(int index, E element);
    25 
    26     public E remove(int index);
    27 
    28     public E get(int index);
    29 
    30 
    31     public E set(int index, E element);
    32 
    33 
    34     public int indexOf(Object o);
    35 
    36     public void clear();
    37 
    38     String toString();
    39 
    40 
    41 //    public boolean remove(Object o);
    42 
    43 
    44 //    public Iterator<E> iterator();
    45 
    46 
    47 //    public Object[] toArray();
    48 
    49 
    50 //    public <T> T[] toArray(T[] a);
    51 
    52 
    53 //    public boolean containsAll(Collection<?> c);
    54 //
    55 //
    56 //    public boolean addAll(Collection<? extends E> c);
    57 //
    58 //
    59 //    public boolean addAll(int index, Collection<? extends E> c) ;
    60 //
    61 //
    62 //    public boolean removeAll(Collection<?> c);
    63 //
    64 //
    65 //    public boolean retainAll(Collection<?> c);
    66 
    67 
    68 //    public int lastIndexOf(Object o);
    69 //
    70 //
    71 //    public ListIterator<E> listIterator();
    72 //
    73 //
    74 //    public ListIterator<E> listIterator(int index);
    75 //
    76 //
    77 //    public List<E> subList(int fromIndex, int toIndex);
    78 
    79 }

    抽象类:MyAbstractList

     1 package day2_19.abstractClass;
     2 
     3 import day2_19.inter.MyList;
     4 
     5 /**
     6  *
     7  * 用于实现arryList 和 linkedList中那些相同的方法
     8  *
     9  * @Author Tianhao
    10  * @create 2021-02-19-17:46
    11  */
    12 
    13 public abstract class MyAbstractList<E> implements MyList<E> {
    14     protected int size;
    15 
    16     /**
    17      * 获取元素个数
    18      * @return 元素个数
    19      */
    20     @Override
    21     public int size() {
    22         return size;
    23     }
    24 
    25     /**
    26      * 判断集合是否为空
    27      * @return
    28      */
    29     @Override
    30     public boolean isEmpty() {
    31         return size == 0;
    32     }
    33 
    34     /**
    35      * 判断集合是否包含指定元素
    36      * indexOf(Object o):寻找对应的元素,如果找到了返回元素的索引,如果没有找到返回 -1
    37      * @param o
    38      * @return
    39      */
    40     @Override
    41     public boolean contains(Object o) {
    42         return indexOf(o) != -1;
    43     }
    44 
    45 
    46     /**
    47      * 在集合的最后添加一个元素,也就是在索引为size处添加一个元素
    48      * @param e
    49      * @return
    50      */
    51     @Override
    52     public boolean add(E e) {
    53         add(size,e);
    54         return true;
    55     }
    56 }

    自定义(单链表)集合类:

      1 package day2_19.linked;
      2 
      3 import day2_19.abstractClass.MyAbstractList;
      4 
      5 /**
      6  * 
      7  * 自定义(单链表)集合类
      8  *
      9  * @Author Tianhao
     10  * @create 2021-02-19-18:01
     11  */
     12 public class MyLinkedList<E> extends MyAbstractList<E> {
     13 
     14     private Node<E> first;
     15 
     16     private static class Node<E>{
     17         E element;
     18         Node<E> next;
     19         Node(E element,Node<E> next){
     20             this.element = element;
     21             this.next = next;
     22         }
     23     }
     24 
     25 
     26 
     27     /**
     28      * 在指定索引index处插入指定元素
     29      * @param index 注意:index >= 0 && index <= size (是可以插入到最后一个元素的下一个位置的)
     30      * @param element
     31      */
     32     @Override
     33     public void add(int index, E element) {
     34         checkPositionIndex(index);//判断index >=0 && index <= size
     35         if (index == 0) {//这里不管first是否为null,都是没有问题的
     36             //如果最开始的first为null,则插入的节点为node(element,null),被first指向
     37             //如果最开始的first不为null,则插入的节点为node(element,first),除了被first指向,它还指向最开始的那个first
     38             first = new Node(element, first);
     39         } else {//插入位置索引不是0
     40             Node<E> pre = node(index - 1);//前一个节点
     41             Node<E> next = pre.next;//后一个节点
     42             pre.next = new Node(element,next);//前一个节点指向插入的节点,这个插入的节点指向后一个节点
     43         }
     44         size++;
     45     }
     46 
     47 
     48     private void checkPositionIndex(int index) {
     49         if (!isPositionIndex(index)) {
     50             throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size);
     51         }
     52     }
     53 
     54     private boolean isPositionIndex(int index) {
     55         return index >= 0 && index <= size;
     56     }
     57 
     58     /**
     59      * 移除集合中指定索引的元素,并返回这个元素
     60      * @param index
     61      * @return
     62      */
     63     @Override
     64     public E remove(int index) {
     65         checkElementIndex(index);
     66         Node<E> oldNode;
     67         if (index==0) {
     68             oldNode = first;
     69             first = first.next;
     70             size--;
     71             return oldNode.element;
     72         }
     73         //先从一般的规律入手,写下来,再看特殊情况,
     74         //如果index=0,那么index-1就为负数,肯定是不行的,所以才有上面if (index==0) 的情况
     75         Node<E> pre = node(index - 1);
     76         oldNode = pre.next;
     77         pre.next = oldNode.next;
     78         size--;
     79         return oldNode.element;
     80     }
     81 
     82     /**
     83      * 获取指定索引(节点)处的元素
     84      * 因为增删改都是基于先找到元素,所以这个方法最先实现比较好
     85      * @param index
     86      * @return
     87      */
     88     @Override
     89     public E get(int index) {
     90         checkElementIndex(index);
     91         return node(index).element;
     92 
     93     }
     94 
     95     /**
     96      * 检查指定索引,如果集合中不存在这个指定索引,则抛出异常
     97      * @param index
     98      */
     99     private void checkElementIndex(int index) {
    100         if (!isElementIndex(index)) {
    101             throw new IndexOutOfBoundsException("Index: " + index + ",Size: " + size);
    102         }
    103     }
    104 
    105     /**
    106      * 找到指定索引index对应的Node节点
    107      * @param index
    108      * @return
    109      */
    110     private Node<E> node(int index) {
    111         //获取集合第一个元素first
    112         Node<E> x = first;
    113         //通过x.next,循环遍历找到指定索引index对应的Node节点
    114         for (int i = 0; i < index; i++) {
    115             x = x.next;
    116         }
    117         return x;
    118     }
    119 
    120     /**
    121      * 判断集合中是否存在指定索引
    122      * @param index
    123      * @return
    124      */
    125     private boolean isElementIndex(int index) {
    126         return index >= 0 && index < size;
    127     }
    128 
    129 
    130     /**
    131      * 将指定索引处的元素替换为指定的元素
    132      * @param index 指定的索引
    133      * @param element 将要替换到指定索引处的元素
    134      * @return 返回指定索引处被替换的元素
    135      */
    136     @Override
    137     public E set(int index, E element) {
    138         checkElementIndex(index);
    139         Node<E> node = node(index);
    140         E oldEle = node.element;
    141         node.element = element;
    142         return oldEle;
    143     }
    144 
    145     /**
    146      * 查找第一次出现指定元素o的索引位置
    147      * @param o
    148      * @return 如果有,返回o在集合中的索引;如果没有,返回-1
    149      */
    150     @Override
    151     public int indexOf(Object o) {
    152         int index = 0;
    153         if (o == null) {
    154             //多去理解这种遍历思维
    155             for (Node<E> x = first; x != null; x = x.next) {
    156                 if (x.element == o) {
    157                     return index;
    158                 }
    159                 //还有这种返回索引的思维也要多学习
    160                 index++;
    161             }
    162         } else {
    163             for (Node<E> x = first; x != null; x = x.next) {
    164                 if (o.equals(x.element)) {
    165                     return index;
    166                 }
    167                 index++;
    168             }
    169         }
    170         return -1;
    171     }
    172 
    173     /**
    174      * 清空集合的所有元素
    175      *
    176      * 可达性算法:判断对象是否是一个垃圾的标准
    177      *  选取一个节点,作为GC ROOTS顶点,其他对象或者引用去指向这个GC ROOTS顶点,如果这些对象
    178      *  能够到达这个GC ROOTS顶点,那么这些对象不是垃圾,反之就是。
    179      *
    180      */
    181     @Override
    182     public void clear() {
    183         size = 0;
    184         first = null;
    185     }
    186 
    187     @Override
    188     public String toString() {
    189         if (size == 0) {
    190             return "[]";
    191         }
    192         StringBuilder sb= new StringBuilder();
    193         sb.append('[');
    194         for( Node<E> x = first;x!=null;x=x.next){
    195             sb.append(x.element);
    196             if (x.next == null) {
    197                 return sb.append(']').toString();
    198             }
    199             sb.append(',').append(' ');
    200         }
    201         return sb.toString();
    202     }
    203 }
  • 相关阅读:
    Java实现 LeetCode 343 整数拆分(动态规划入门经典)
    Java实现 LeetCode 342 4的幂
    Java实现 LeetCode 342 4的幂
    Java实现 LeetCode 342 4的幂
    Java实现 LeetCode 341 扁平化嵌套列表迭代器
    Java实现 LeetCode 341 扁平化嵌套列表迭代器
    Java实现 LeetCode 341 扁平化嵌套列表迭代器
    Java实现 LeetCode 338 比特位计数
    H264(NAL简介与I帧判断)
    分享一段H264视频和AAC音频的RTP封包代码
  • 原文地址:https://www.cnblogs.com/zui-ai-java/p/14422828.html
Copyright © 2011-2022 走看看