zoukankan      html  css  js  c++  java
  • 数据结构(二) 线性表链式存储

    原理:用一组任意的存储单元存储线性表元素。

    原理图:

    算法原理:

    1、为了表示数据元素a和他直接后继元素的关系a+1的逻辑关系,对数据元素a来说除了存储本身的数据信息外,再开辟一块空间存储直接后继元素位置,存储数据信息的区域称为数据域,存储直接后继元素位置的区域称为指针域,指针域存储的信息称为指针或者链,两部分数据组成的元素称为结点(Node),

    2、插入元素即为创建新结点的过程

    假设存储数据e的结点为s,将 s 插入大到p —> p-next之间,只需要让 p —> s , s —> p-next做一下指针变化即可

     

    3、删除元素即为重新设置其直接前驱和直接后记元素的指针的过程(原理同上图)

    4、查询元素即为从头部或者尾部遍历的过程

    总结:

    1、相对于顺序存储结构,链表不需要预先分配存储空间,随时分配

    2、插入和删除不需要移动元素,效率更快

    3、存取需要遍历表效率低于顺序表

    实现代码:

    接口定义:

     1 package online.jfree.base.container;
     2 
     3 /**
     4  * author : Guo LiXiao
     5  * date : 2017-6-14  11:46
     6  */
     7 
     8 public interface LineList <E>{
     9 
    10     /**
    11      * lineList 是否为空
    12      * @return
    13      */
    14     boolean isEmpty();
    15 
    16     /**
    17      * 清空 lineList
    18      */
    19     void clear();
    20 
    21     /**
    22      * 获取指定位置元素
    23      * @param index
    24      * @return
    25      */
    26     E get(int index);
    27 
    28     /**
    29      * 获取元素第一次出现的位置
    30      * @param e
    31      * @return
    32      */
    33     int indexOf(E e);
    34 
    35     /**
    36      * 判断 lineList是否包含指定元素
    37      * @param e
    38      * @return
    39      */
    40     boolean contains(E e);
    41 
    42     /**
    43      * 设置指定位置数据,如数据已存在 则覆盖原数据
    44      * @param index
    45      * @param e
    46      * @return
    47      */
    48     E set(int index, E e);
    49 
    50     /**
    51      * 移除指定位置元素
    52      * @param index
    53      * @return
    54      */
    55     E remove(int index);
    56 
    57     /**
    58      * 在lineList结尾插入元素
    59      * @param e
    60      * @return
    61      */
    62     E add(E e);
    63 
    64     /**
    65      * 在index后面插入元素
    66      * @param index
    67      * @param e
    68      * @return
    69      */
    70     E add(int index, E e);
    71 
    72     /**
    73      * 返回lineList长度
    74      * @return
    75      */
    76     int size();
    77 
    78 
    79 
    80 }
    View Code
     1 package online.jfree.base.container.list;
     2 
     3 import online.jfree.base.container.LineList;
     4 
     5 /**
     6  * author : Guo LiXiao
     7  * date : 2017-6-19  10:16
     8  */
     9 
    10 public abstract class AbstractLineList<E> implements LineList<E> {
    11 
    12     protected int size;
    13 
    14     protected abstract void init();
    15 
    16     @Override
    17     public boolean isEmpty() {
    18         return this.size == 0;
    19     }
    20 
    21     @Override
    22     public void clear() {
    23         init();
    24     }
    25 
    26     @Override
    27     public int size() {
    28         return this.size;
    29     }
    30 
    31     @Override
    32     public boolean contains(E e) {
    33         return indexOf(e) > 0;
    34     }
    35 }
    View Code

    单链表实现(单链表结点只有一个指针域,存储直接前驱或者直接后继结点):

      1 package online.jfree.base.container.list;
      2 
      3 import online.jfree.base.container.LineList;
      4 
      5 /**
      6  * 线性表的链式存储结构
      7  * author : Guo LiXiao
      8  * date : 2017-6-7  14:52
      9  */
     10 
     11 public class LinkedLineList<E> extends AbstractLineList<E> implements LineList<E> {
     12 
     13     transient Node<E> first;
     14 
     15     public LinkedLineList() {
     16     }
     17 
     18     @Override
     19     protected void init() {
     20         this.size = 0;
     21         first = null;
     22     }
     23 
     24     /**
     25      * 根据索引获取元素
     26      * @param index
     27      * @return
     28      */
     29     protected Node<E> node(int index) {
     30         Node<E> x = first;
     31         for (int i = 0; i < index; i++)
     32             x = x.next;
     33         return x;
     34     }
     35 
     36     /**
     37      * 校验列表索引越界
     38      *
     39      * @param index
     40      */
     41     private void checkCapacity(int index) {
     42         if (index >= size || index < 0)
     43             throw new IndexOutOfBoundsException(new StringBuffer("[index : ").append(index).append("] , [size : ").append(size).append("] ").toString());
     44     }
     45 
     46 
     47     @Override
     48     public E get(int index) {
     49         checkCapacity(index);
     50         return node(index).item;
     51     }
     52 
     53     @Override
     54     public int indexOf(E e) {
     55         int index = 0;
     56         for (Node<E> x = first; x != null; x = x.next) {
     57             if (e == null && x.item == null || e.equals(x.item))
     58                 return index;
     59             index++;
     60         }
     61         return -1;
     62     }
     63 
     64     @Override
     65     public E set(int index, E e) {
     66         checkCapacity(index);
     67         Node<E> node = node(index);
     68         E old = node.item;
     69         node.item = e;
     70         return old;
     71     }
     72 
     73     @Override
     74     public E remove(int index) {
     75         checkCapacity(index);
     76         if (index == 0) {
     77             Node<E> node = first;
     78             Node<E> next = node.next;
     79             first = next;
     80             size --;
     81             return first.item;
     82         } else {
     83             Node<E> pre = node(index - 1);
     84             Node<E> node = pre.next;
     85             Node<E> next = node.next;
     86             pre.next = next;
     87             size --;
     88             return node.item;
     89         }
     90     }
     91 
     92     @Override
     93     public E add(E e) {
     94         if (size == 0) {
     95             first = new Node<>(e, null);
     96             size ++;
     97             return first.item;
     98         }
     99         return add(size - 1, e);
    100     }
    101 
    102     @Override
    103     public E add(int index, E e) {
    104         checkCapacity(index);
    105         Node<E> node = node(index);
    106         Node<E> next = node.next;
    107         node.next = new Node<>(e, next);
    108         size ++;
    109         return node.next.item;
    110     }
    111 
    112     private static final class Node<E> {
    113         E item;
    114         Node<E> next;
    115 
    116         public Node(E item, Node<E> next) {
    117             this.item = item;
    118             this.next = next;
    119         }
    120     }
    121 }
    View Code

    双向链表实现(双向链表结点有两个指针域,存储直接前驱和直接后继结点):

      1 package online.jfree.base.container.list;
      2 
      3 import online.jfree.base.container.LineList;
      4 
      5 /**
      6  * 线性表 双向链表
      7  * author : Guo LiXiao
      8  * date : 2017-6-19  9:59
      9  */
     10 
     11 public class DualLinkedLineList<E> extends AbstractLineList<E> implements LineList<E> {
     12 
     13     private transient Node<E> first;
     14     private transient Node<E> last;
     15 
     16     /**
     17      * 根据索引获取元素
     18      *
     19      * @param index
     20      * @return
     21      */
     22     protected Node<E> node(int index) {
     23         if (index < (size >> 1)) {
     24             Node<E> x = first;
     25             for (int i = 0; i < index; i++)
     26                 x = x.next;
     27             return x;
     28         } else {
     29             Node<E> x = last;
     30             for (int i = size - 1; i > index; i--)
     31                 x = x.prev;
     32             return x;
     33         }
     34     }
     35 
     36     /**
     37      * 校验列表索引越界
     38      *
     39      * @param index
     40      */
     41     private void checkCapacity(int index) {
     42         if (index >= size || index < 0)
     43             throw new IndexOutOfBoundsException(new StringBuffer("[index : ").append(index).append("] , [size : ").append(size).append("] ").toString());
     44     }
     45 
     46 
     47     @Override
     48     protected void init() {
     49         this.size = 0;
     50         first = null;
     51         last = null;
     52     }
     53 
     54     @Override
     55     public E get(int index) {
     56         checkCapacity(index);
     57         return node(index).item;
     58     }
     59 
     60     @Override
     61     public int indexOf(E e) {
     62         int index = 0;
     63         for (Node<E> x = first; x != null; x = x.next) {
     64             if (e == null && x.item == null || e.equals(x.item))
     65                 return index;
     66             index++;
     67         }
     68         return -1;
     69     }
     70 
     71     @Override
     72     public E set(int index, E e) {
     73         checkCapacity(index);
     74         Node<E> node = node(index);
     75         E old = node.item;
     76         node.item = e;
     77         return old;
     78     }
     79 
     80     @Override
     81     public E remove(int index) {
     82         checkCapacity(index);
     83         Node<E> node = node(index);
     84         final E e = node.item;
     85         final Node<E> next = node.next;
     86         final Node<E> prev = node.prev;
     87         if (prev == null) {
     88             first = next;
     89             first.prev = null;
     90         } if (next == null){
     91             last = prev;
     92             last.next = null;
     93         } else {
     94             prev.next = next;
     95             next.prev = prev;
     96         }
     97         size--;
     98         return e;
     99     }
    100 
    101     @Override
    102     public E add(E e) {
    103         if (first == null) {
    104             first = new Node<>(null, e, null);
    105             last = first;
    106             size ++;
    107             return first.item;
    108         }
    109         return add(size - 1, e);
    110     }
    111 
    112     @Override
    113     public E add(int index, E e) {
    114         checkCapacity(index);
    115         Node<E> node = node(index);
    116         Node<E> next = node.next;
    117         node.next = new Node<>(node, e, next);
    118         if (next == null) last = node.next;
    119         size ++;
    120         return node.next.item;
    121     }
    122 
    123     private static final class Node<E> {
    124         E item;
    125         Node<E> prev;
    126         Node<E> next;
    127 
    128         public Node(Node<E> prev, E item, Node<E> next) {
    129             this.item = item;
    130             this.prev = prev;
    131             this.next = next;
    132         }
    133     }
    134 
    135 }
    View Code
  • 相关阅读:
    技术部新年开工第一场会议
    mockjs学习总结(方便前端模拟数据,加快开发效率)
    vue开发后台管理系统小结
    网站代码、图片优化汇总
    前端seo小结,网页代码优化
    Java 并发编程之锁的实现
    python之格式化输出
    python七类之列表元组
    python七类之集合
    函数风云序列之函数初现
  • 原文地址:https://www.cnblogs.com/darkwind/p/7049079.html
Copyright © 2011-2022 走看看