• 自己实现Linkedlist,实现其常用的增、删、查的方法


      1 /**自己实现linkedlsit
      2  * 添加 addFirst(E e) addLast(E e)  add(E e)  add(int index,E e)
      3  * 获取 get(int index)  getLast() getFirst()
      4  * 删除 removeFirst()  remvoeLast()  remove()  remove(int index)  remove(Object o)
      5  * @author cuiyc
      6  * @version 1.0
      7  * @date 2021/6/5 10:22
      8  */
      9 public class LinkedListDemo2<E> {
     10     /**
     11      * list的长度
     12      */
     13     private int size=0;
     14     /**
     15      * linkedlist的首节点
     16      */
     17     private Node first;
     18     /**
     19      * linkedlist的末尾节点
     20      */
     21     private Node last;
     22 
     23     /**
     24      * 定义一个静态内部类,即节点,包含前节点、元素、后节点
     25      * @param <E> 泛型参数
     26      */
     27     private static class Node<E>{
     28         E e;
     29         Node prev;
     30         Node next;
     31 
     32         public Node(Node prev,E e,Node next){
     33             this.e=e;this.prev=prev;this.next=next;
     34         }
     35     }
     36 
     37     /**
     38      * 空参构造函数
     39      */
     40     public LinkedListDemo2(){
     41 
     42     }
     43 
     44     /**
     45      * 在linkedlist的头部添加元素
     46      * @param e 要添加的元素
     47      */
     48     private void addFirst(E e){
     49         //向linkedlist的头部添加元素
     50         linkFirst(e);
     51     }
     52 
     53     /**
     54      * 在linkedlist的尾部添加元素
     55      * @param e 要添加的元素
     56      */
     57     private void addLast(E e){
     58         //向linkedlist的尾部添加元素
     59         linkLast(e);
     60     }
     61 
     62     /**
     63      * 添加元素,默认是向linkedlist的尾部添加元素
     64      * @param e 要添加的元素
     65      */
     66     private void add(E e){
     67         addLast(e);
     68     }
     69 
     70     /**
     71      * 向linkedlist的某个位置添加元素
     72      * @param index linkedlist的某个位置
     73      * @param e 要添加的元素
     74      */
     75     private void add(int index,E e){
     76         //1 判断index是否和目前linkedlist的长度相等,如果相等,则表示需要添加到链表的尾部,否则是添加到尾部之前的其他位置
     77         if(index==size){
     78             linkLast(e);
     79         }else {
     80             linkBefore(index,e);
     81         }
     82     }
     83 
     84     /**
     85      * 获取linkedlist的最后一个节点的元素
     86      * @return
     87      */
     88     private E getLast(){
     89         final Node<E> l=last;
     90         if(l==null){
     91             throw  new NoSuchElementException();
     92         }
     93         return l.e;
     94     }
     95 
     96     /**
     97      * 获取linkedlist的第一个节点元素
     98      * @return
     99      */
    100     private E getFirst(){
    101         final Node<E> f=first;
    102         if(f==null){
    103             throw new NoSuchElementException();
    104         }
    105         return f.e;
    106     }
    107 
    108     /**
    109      * 获取某个位置的节点元素
    110      * @param index 位置
    111      * @return
    112      */
    113     private E get(int index){
    114         final Node<E> n=node(index);
    115         if(n==null){
    116             throw new NoSuchElementException();
    117         }
    118         return n.e;
    119     }
    120 
    121     /**
    122      * 移除linkedlist中的第一个元素
    123      */
    124     private void removeFirst(){
    125         //1 找到first
    126         final Node<E> f=first;
    127         if(f==null){
    128             throw new NoSuchElementException();
    129         }
    130         unLinkFirst(f);
    131     }
    132 
    133     /**
    134      * 移除linkedlist的最后一个元素
    135      */
    136     private void removeLast(){
    137         //1 找到last node
    138         final Node<E> l=last;
    139         if(l==null){
    140             throw new NoSuchElementException();
    141         }
    142         unLinkLast(l);
    143     }
    144 
    145     /**
    146      * 移除linkedlist中的元素,模式是移除最后一个元素
    147      */
    148     private void remove(){
    149         removeLast();
    150     }
    151 
    152     /**
    153      * 移除linkedlist中的某个位置的元素
    154      * @param index 位置
    155      */
    156     private void remove(int index){
    157         final Node<E> n=node(index);
    158         unLink(n);
    159     }
    160 
    161     /**
    162      * 移除linkedlist中的某个元素的置
    163      * @param o 元素的值
    164      * @return
    165      */
    166     private Boolean remove(Object o){
    167         //如果元素的值为null 则循环判断链表,如果节点的值为null,则删除那个节点
    168         if(o==null){
    169             for (Node<E> n=first;n!=null;n=n.next){
    170                 if(n.e==null){
    171                     unLink(n);
    172                     return true;
    173                 }
    174             }
    175         }else {
    176             //如果元素的值不为null,则循环判断链表,如果节点的值等于当前元素的值,则删除当前节点。
    177             for (Node<E> n=first;n!=null;n=n.next){
    178                 if(o.equals(n.e)){
    179                     unLink(n);
    180                     return true;
    181                 }
    182             }
    183         }
    184         return false;
    185     }
    186 
    187     /**
    188      * 移除linkedlist中的某个节点
    189      * @param n
    190      */
    191     private E unLink(Node<E> n) {
    192         //拿到当前节点的元素值
    193         final E element=n.e;
    194         //拿到当前节点的上一个节点prev
    195         final Node<E>prev=n.prev;
    196         //拿到当前节点的下一个节点next
    197         final Node<E>next=n.next;
    198         //判断当前节点的上一节点是否为空,如果为空 则下一节点为first节点 如果不为空,则上一个节点的下一节点为next。并将当前节点的前一节点置空
    199         if(prev==null){
    200             first=next;
    201         }else {
    202             prev.next=next;
    203             n.prev=null;
    204         }
    205         //判断下一节点是否为空,如果为空,则上一节点为last节点 如果不为空 则当前节点的下一节点的上个节点是prev,并将当前节点的next置空
    206         if(next==null){
    207             last=prev;
    208         }else {
    209             next.prev=prev;
    210             n.next=null;
    211         }
    212         //当前节点的元素置空
    213         n.e=null;
    214         //元素的长度减1
    215         size--;
    216         return element;
    217     }
    218 
    219 
    220     /**
    221      * 移除linkedlist的最后一个元素的实现方法
    222      * @param l
    223      */
    224     private E unLinkLast(Node<E> l) {
    225         //1 找到最后一个节点的元素
    226         final E element=l.e;
    227         //2 找到最后一个节点前的那个节点
    228         final Node<E> prev=l.prev;
    229         //将最后一个节点的元素置空 最后一个节点的前一个节点指针置空 将倒数第二个节点数组为last节点
    230         l.e=null;
    231         l.prev=null;
    232         last=prev;
    233         //判断如果倒数第二个节点为空,则first也为空 如果不为空,则其next节点设置为空。
    234         if(prev==null){
    235             first=null;
    236         }else {
    237             prev.next=null;
    238         }
    239         size--;
    240         return element;
    241     }
    242 
    243 
    244     private E unLinkFirst(Node<E> f){
    245         //1 拿到第一个节点的元素
    246         final E element=f.e;
    247         //拿到第二个节点
    248         final Node<E> next=f.next;
    249         //将第一个节点的元素置空 第一个节点的next节点置空 再将next节点设置为first节点
    250         f.e=null;
    251         f.next=null;//有助于垃圾回收
    252         first=next;
    253         //判断next节点是否为空 如果为空,则last节点也为空,如果不为空,则将next的prev节点置为空。
    254         if(next==null){
    255             last=null;
    256         }else {
    257             next.prev=null;
    258         }
    259         size--;
    260         return element;
    261     }
    262 
    263     /**
    264      * 向linkedlist的头部添加元素的实现方法
    265      * @param e 要添加的元素
    266      */
    267     private void linkFirst(E e){
    268         //1 找到first节点
    269         final Node<E> f=first;
    270         //2 创建要添加的新的node节点
    271         final Node<E> newNode=new Node<>(null,e,f);
    272         //3 将要添加的新的node节点定义为first节点
    273         first=newNode;
    274         //4 判断之前的f即fist节点的有无,如果没有,表示添加的新的节点即是first节点也是last节点。如果之前有first节点,则将之前的
    275         //first的节点的prev执行新的first节点。
    276         if(f==null){
    277             last=newNode;
    278         }else {
    279             f.prev=newNode;
    280         }
    281         size++;
    282     }
    283 
    284     /**
    285      * 向linkedlist的尾部添加元素的实现方法
    286      * @param e 要添加的元素
    287      */
    288     private void linkLast(E e){
    289         //1 找到last节点
    290         final Node<E>l=last;
    291         //2 创建要添加的新的node节点,前一节点指向之前的last节点,后一节点指向null
    292         final Node<E>newNode=new Node<>(l,e,null);
    293         //3 将新创建的node节点定义为last节点
    294         last=newNode;
    295         //4 判断之前的定义的last节点l是否为空,如果为空,则表示之前没有节点存在,即新添加的元素即是first节点也是last节点
    296         // 如果之前定义的last节点l不为空,则将其next节点指向新创建的节点
    297         if(l==null){
    298             first=newNode;
    299         }else {
    300             l.next=newNode;
    301         }
    302         size++;
    303     }
    304 
    305     /**
    306      * 向linkedlist的除了尾部的其他位置添加元素
    307      * @param index  list的位置
    308      * @param e 要添加的元素
    309      */
    310     private void linkBefore(int index,E e){
    311         //1 通过index 在linkedlist中找到那个节点
    312         final Node<E> succ=node(index);
    313         //2 找到succ的前一个节点pred节点
    314         final Node<E> pred=succ.prev;
    315         //3 新建一个节点,元素是e 其下一节点是succ节点,上一个节点是pred节点
    316         final Node<E> newNode=new Node<>(pred,e,succ);
    317         //4 通过index找到的那个节点,设置其prev节点为newNode节点。
    318         succ.prev=newNode;
    319         //5 判断之前的succ的prev节点,是否为空。如果为空,表示newNode将是first节点,否则pred的next节点为newNode
    320         if(pred==null){
    321             first=newNode;
    322         }else {
    323             pred.next=newNode;
    324         }
    325         //6 linkedlist的长度加1
    326         size++;
    327     }
    328 
    329     /**
    330      * 通过index来查询linkedlist中的某个元素。
    331      * @param index
    332      * @return
    333      */
    334     private Node<E> node(int index) {
    335         //判断 index是分布在linkedlsit链表的左半部分还是右半部分  size>>1 即是size右移1位,size的0.5倍
    336         if(index<(size>>1)){
    337             Node<E> x=first;
    338             for (int i = 0; i < index; i++) {
    339                 x=x.next;
    340             }
    341             return x;
    342         }else {
    343             Node<E> x=last;
    344             for (int i=size-1;i>size;i--){
    345                 x=x.prev;
    346             }
    347             return x;
    348         }
    349     }
    350 }


    作者:RichardCui
    出处:https://www.cnblogs.com/yachao1120/
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。该文章也同时发布在我的独立博客中-RichardCuiBlog

  • 相关阅读:
    20165320 第四次实验 Android开发
    20165320 第十周课上测试补做
    20165320 第九周课下测试补做
    20165320 Java实验三:敏捷开发与XP实践
    20165320 第九周学习总结
    20165320 第八周课下补做
    20165320 结对编程第二周
    20165320 第八周学习总结
    20165329 Java实验二:面向对象编程
    第十周课上测试补做
  • 原文地址:https://www.cnblogs.com/yachao1120/p/14853349.html
Copyright © 2020-2023  润新知