• 第三章 线性表1(顺序存储和单链表)


    3.1线性表及抽象数据类型

    线性表的(linear list)是n个类型相同数据元素的有限序列,n定义线性表的长度,n=0为空表

    线性表中相邻的两个元素不一定存储在连续的内存空间中,除非时用数组实现的。

     线性表对应的java的集合(List)

      1 package com.datastructure.chapter03;
      2 
      3 /** 
      4  * @ClassName: List 
      5  * @Description: 线性表对应java中的集合List  共11个方法
      6  * @author 
      7  * @date 2018年3月6日 下午11:17:26 
      8  *  
      9  */
     10 public interface List {
     11 
     12     
     13     /** 
     14      * @Title: getSize 
     15      * @Description: 返回线性表的大小,即数据元素的个数 
     16      * @param @return  
     17      * @return int   
     18      * @throws 
     19      */
     20     public int getSize();
     21     
     22     /** 
     23      * @Title: isEmpty 
     24      * @Description:  线性表为空返回true,否则返回false
     25      * @param @return  
     26      * @return boolean   
     27      * @throws 
     28      */
     29     public boolean isEmpty();
     30     
     31     /** 
     32      * @Title: contains 
     33      * @Description:  判断线性表中是否包含某个元素
     34      * @param @param e
     35      * @param @return  
     36      * @return boolean   
     37      * @throws 
     38      */
     39     public boolean contains(Object e);
     40     
     41     /** 
     42      * @Title: indexOf 
     43      * @Description:  返回数据元素e在线性表中的序号
     44      * @param @param e
     45      * @param @return  
     46      * @return int   
     47      * @throws 
     48      */
     49     public int indexOf(Object e);
     50     
     51     /** 
     52      * @Title: insert 
     53      * @Description:  将数据元素e插入到线性表i号位置
     54      * @param @param i
     55      * @param @param e
     56      * @param @throws Exception  下标越界的异常 
     57      * @return void   
     58      * @throws 
     59      */
     60     public void insert(int i,Object e) throws Exception;
     61     
     62     
     63     /** 
     64      * @Title: insertBefore 
     65      * @Description: 将数据元素e插入到元素obj之前 
     66      * @param @param obj
     67      * @param @param e
     68      * @param @return  
     69      * @return boolean   
     70      * @throws 
     71      */
     72     public boolean insertBefore(Object obj,Object e);
     73     
     74     
     75     /** 
     76      * @Title: insertAfter 
     77      * @Description: 将数据元素e插入到元素obj之后
     78      * @param @param obj
     79      * @param @param e
     80      * @param @return  
     81      * @return boolean   
     82      * @throws 
     83      */
     84     public boolean insertAfter(Object obj,Object e);
     85     
     86     /**
     87      * s
     88      * @Title: remove 
     89      * @Description: 删除序号为i的元素
     90      * @param @param i
     91      * @param @return
     92      * @param @throws Exception 下标越界的异常  
     93      * @return Object   
     94      * @throws
     95      */
     96     public Object remove(int i) throws Exception;
     97     
     98     
     99     /** 
    100      * @Title: remove 
    101      * @Description:  移除线性表中与e相同元素
    102      * @param @param e
    103      * @param @return  
    104      * @return boolean   
    105      * @throws 
    106      */
    107     public boolean remove(Object e);
    108     
    109     /** 
    110      * @Title: replace 
    111      * @Description:  替换表中序号为i的元素,返回原数据元素
    112      * @param @param i
    113      * @param @param e
    114      * @param @return
    115      * @param @throws Exception  
    116      * @return Object   
    117      * @throws 
    118      */
    119     public Object replace(int i,Object e) throws Exception;
    120     
    121     /**
    122      * 
    123      * @Title: get 
    124      * @Description:  返回线性表中序号为i的元素
    125      * @param @param i
    126      * @param @return
    127      * @param @throws Exception  
    128      * @return Object   
    129      * @throws
    130      */
    131     public Object get(int i) throws Exception;
    132     
    133     
    134     
    135     
    136 }
    View Code

     list接口中异常的类:

     1 package com.datastructure.chapter03;
     2 
     3 /** 
     4  * @ClassName: OutOfBoundaryException 
     5  * @Description: 角标越界的异常
     6  * @author 
     7  * @date 2018年3月8日 下午10:52:36 
     8  *  
     9  */
    10 @SuppressWarnings("serial")
    11 public class OutOfBoundaryException extends RuntimeException {
    12     
    13     public OutOfBoundaryException(String err){
    14         super(err);
    15     }
    16     
    17 }
    View Code

    由于list接口中的所有元素都是Object,不利于比较;比如:String的compareTo与equal,基本类型的数据用关系运算符进行比较;所以要制定一个比较策略,抽出一个比较的接口

     1 package com.datastructure.chapter03;
     2 
     3 public interface Strategy {
     4     
     5     /** 
     6      * @Title: equal 
     7      * @Description:  判断两个元素是否相等
     8      * @param @param obj1
     9      * @param @param obj2
    10      * @param @return  
    11      * @return boolean   
    12      * @throws 
    13      */
    14     public boolean equal(Object obj1,Object obj2);
    15     
    16     
    17     
    18     /** 
    19      * @Title: compare 
    20      * @Description:  obj1>obj2 返回1
    21      * @param @param obj1
    22      * @param @param obj2
    23      * @param @return  
    24      * @return int   
    25      * @throws 
    26      */
    27     public int compare(Object obj1,Object obj2);
    28     
    29 }
    View Code

     比如下面的学生类:

     1 package com.datastructure.chapter03;
     2 
     3 /** 
     4  * @ClassName: Student 
     5  * @Description: 学生类
     6  * @author 
     7  * @date 2018年3月8日 下午11:02:08 
     8  *  
     9  */
    10 public class Student {
    11     
    12     private String sId;
    13 
    14     public String getsId() {
    15         return sId;
    16     }
    17 
    18     public void setsId(String sId) {
    19         this.sId = sId;
    20     }
    21     
    22     
    23 }
    View Code

    比较实现类:

     1 package com.datastructure.chapter03;
     2 
     3 /** 
     4  * @ClassName: StudentStrategy 
     5  * @Description: 具体的比较实现类
     6  * @author 
     7  * @date 2018年3月8日 下午11:07:44 
     8  *  
     9  */
    10 public class StudentStrategy implements Strategy {
    11 
    12     @Override
    13     public boolean equal(Object obj1, Object obj2) {
    14         
    15         if(obj1 instanceof Student && obj2 instanceof Student){
    16             
    17             Student s1 = (Student) obj1;
    18             
    19             Student s2 = (Student) obj2;
    20             
    21             return s1.getsId().equals(s2.getsId());
    22         }
    23         return false;
    24     }
    25 
    26     @Override
    27     public int compare(Object obj1, Object obj2) {
    28         
    29         if(obj1 instanceof Student && obj2 instanceof Student){
    30             Student s1 = (Student) obj1;
    31             Student s2 = (Student) obj2;
    32             return s1.getsId().compareTo(s2.getsId());
    33         }else{
    34             return obj1.toString().compareTo(obj2.toString());
    35         }
    36         
    37     }
    38 
    39 }
    View Code

     3.2 线性表的顺序存储与实现

    线性表的顺序存储是用一组地址连续的存储单元依次存储线性表的数据元素。

    线性表中序号为i的数据元素的存储地址LOC(ai)与序号为i+1的数据元素的存储地址LOC(ai+1)之间的关系为:LOC(ai+1) = LOC(ai) + K(每个元素占用K个存储单元);数组是采用顺序存储的结构。若是线性表中存储的是对象时,数组存放的是对象的引用。

    线性表的顺序存储的特点:以数据元素在机内存储地址相邻来表示线性表中数据元素之间的逻辑关系。

    线性表的顺讯存储的实例ListArray:

      1 package com.datastructure.chapter03.interfacesImpl;
      2 
      3 import com.datastructure.chapter03.exception.OutOfBoundaryException;
      4 import com.datastructure.chapter03.interfaces.List;
      5 import com.datastructure.chapter03.interfaces.Strategy;
      6 
      7 public class ListArray implements List {
      8 
      9     private final int LEN = 8;// 数组的默认大小
     10 
     11     private Strategy strategy;// 数据元素比较策略
     12 
     13     private int size;
     14 
     15     private Object[] elements;// 数据元素数组
     16 
     17     public ListArray() {
     18         this(new DefaultStrategy());
     19     }
     20 
     21     public ListArray(Strategy strategy) {
     22         this.strategy = strategy;
     23         size = 0;
     24         elements = new Object[LEN];
     25     }
     26 
     27     /*
     28      * (非 Javadoc) <p>Title: getSize</p> <p>Description: 返回线性表的大小,即数据元素的个数</p>
     29      * 
     30      * @return
     31      * 
     32      * @see com.datastructure.chapter03.interfaces.List#getSize()
     33      */
     34     @Override
     35     public int getSize() {
     36         return size;
     37     }
     38 
     39     /*
     40      * (非 Javadoc) <p>Title: isEmpty</p> <p>Description:
     41      * 如果线性表为空返回true,否则返回false</p>
     42      * 
     43      * @return
     44      * 
     45      * @see com.datastructure.chapter03.interfaces.List#isEmpty()
     46      */
     47     @Override
     48     public boolean isEmpty() {
     49         return size == 0;
     50     }
     51 
     52     /*
     53      * (非 Javadoc) <p>Title: contains</p> <p>Description: 判断线性表是否包含数据元素e</p>
     54      * 
     55      * @param e
     56      * 
     57      * @return
     58      * 
     59      * @see
     60      * com.datastructure.chapter03.interfaces.List#contains(java.lang.Object)
     61      */
     62     @Override
     63     public boolean contains(Object e) {
     64 
     65         for (int i = 0; i < size; i++)
     66             if (strategy.equal(e, elements[i]))
     67                 return true;
     68         return false;
     69     }
     70 
     71     /* (非 Javadoc) 
     72      * <p>Title: indexOf</p> 
     73      * <p>Description: 返回数据元素e在线性表中的序号</p> 
     74      * @param e
     75      * @return 
     76      * @see com.datastructure.chapter03.interfaces.List#indexOf(java.lang.Object) 
     77      */
     78     @Override
     79     public int indexOf(Object e) {
     80         for(int i=0;i<size;i++)
     81             if(strategy.equal(e, elements[i]))
     82                 return i;
     83         return -1;
     84     }
     85 
     86     /* (非 Javadoc) 
     87      * <p>Title: insert</p> 
     88      * <p>Description: 将数据元素e插入到线性表中i号位置</p> 
     89      * @param i
     90      * @param e
     91      * @throws OutOfBoundaryException 
     92      * @see com.datastructure.chapter03.interfaces.List#insert(int, java.lang.Object) 
     93      */
     94     @Override
     95     public void insert(int i, Object e) throws OutOfBoundaryException {
     96         if(i<0||i>size)
     97             throw new OutOfBoundaryException("错误,指定的插入序号越界");
     98         
     99         if(size >= elements.length)
    100             expandSpace();
    101         for(int j=size;j>i;j--)
    102             elements[j] = elements[j-1];
    103         elements[i] = e; size++;
    104         return ;
    105     }
    106 
    107     /** 
    108      * @Title: expandSpace 
    109      * @Description: 进行数组扩容 
    110      * @param   
    111      * @return void   
    112      * @throws 
    113      */
    114     private void expandSpace() {
    115         Object[] a = new Object[elements.length*2];
    116         for(int i=0;i<elements.length;i++)
    117             a[i] = elements[i];
    118         elements = a;
    119     }
    120 
    121     /* (非 Javadoc) 
    122      * <p>Title: insertBefore</p> 
    123      * <p>Description: 将数据袁术e插入到元素obj之前</p> 
    124      * @param obj
    125      * @param e
    126      * @return 
    127      * @see com.datastructure.chapter03.interfaces.List#insertBefore(java.lang.Object, java.lang.Object) 
    128      */
    129     @Override
    130     public boolean insertBefore(Object obj, Object e) {
    131         int i = indexOf(obj);
    132         if(i<0)return false;
    133         insert(i,e);
    134         return true;
    135     }
    136 
    137     /* (非 Javadoc) 
    138      * <p>Title: insertAfter</p> 
    139      * <p>Description: 插入到元素obj之后</p> 
    140      * @param obj
    141      * @param e
    142      * @return 
    143      * @see com.datastructure.chapter03.interfaces.List#insertAfter(java.lang.Object, java.lang.Object) 
    144      */
    145     @Override
    146     public boolean insertAfter(Object obj, Object e) {
    147         int i = indexOf(obj);
    148         if(i<0)return false;
    149         insert(i+1,e);
    150         return true;
    151     }
    152 
    153     /* (非 Javadoc) 
    154      * <p>Title: remove</p> 
    155      * <p>Description: 删除线性表中序号为i的元素,并返回之</p> 
    156      * @param i
    157      * @return
    158      * @throws OutOfBoundaryException 
    159      * @see com.datastructure.chapter03.interfaces.List#remove(int) 
    160      */
    161     @Override
    162     public Object remove(int i) throws OutOfBoundaryException {
    163         if(i<0 || i>size)
    164             throw new OutOfBoundaryException("错误,指定的删除序号越界");
    165         Object obj = elements[i];
    166         for (int j = i; j < size - 1; j++) 
    167             elements[j] = elements[j+1];
    168         elements[--size] = null;
    169         return obj;
    170     }
    171 
    172     /* (非 Javadoc) 
    173      * <p>Title: remove</p> 
    174      * <p>Description: 删除线性表中第一个与e相同的元素</p> 
    175      * @param e
    176      * @return 
    177      * @see com.datastructure.chapter03.interfaces.List#remove(java.lang.Object) 
    178      */
    179     @Override
    180     public boolean remove(Object e) {
    181         int i = indexOf(e);
    182         if(i<0) return false;
    183         remove(i);
    184         return true;
    185     }
    186 
    187     /* (非 Javadoc) 
    188      * <p>Title: replace</p> 
    189      * <p>Description: 替换线性表中序号为i的数据元素为e,返回原数据元素</p> 
    190      * @param i
    191      * @param e
    192      * @return
    193      * @throws OutOfBoundaryException 
    194      * @see com.datastructure.chapter03.interfaces.List#replace(int, java.lang.Object) 
    195      */
    196     @Override
    197     public Object replace(int i, Object e) throws OutOfBoundaryException {
    198         if(i<0|| i>=size)
    199             throw new OutOfBoundaryException("错误,指定的序号越界");
    200         
    201         Object obj = elements[i];
    202         elements[i] = e;
    203         return obj;
    204     }
    205 
    206     /* (非 Javadoc) 
    207      * <p>Title: get</p> 
    208      * <p>Description: 返回线性表中序号为i的数据元素</p> 
    209      * @param i
    210      * @return
    211      * @throws OutOfBoundaryException 
    212      * @see com.datastructure.chapter03.interfaces.List#get(int) 
    213      */
    214     @Override
    215     public Object get(int i) throws OutOfBoundaryException {
    216         if(i<0 || i>=size)
    217             throw new OutOfBoundaryException("错误,指定的序号越界。");
    218         return elements[i];
    219     }
    220 
    221 }
    View Code

    默认的策略类DefaultStrategy类的实现:

     1 package com.datastructure.chapter03.interfacesImpl;
     2 
     3 import com.datastructure.chapter03.interfaces.Strategy;
     4 
     5 public class DefaultStrategy implements Strategy {
     6 
     7     /* (非 Javadoc) 
     8      * <p>Title: equal</p> 
     9      * <p>Description: 比较的方法(自己写的,不是书上的)</p> 
    10      * @param obj1
    11      * @param obj2
    12      * @return 
    13      * @see com.datastructure.chapter03.interfaces.Strategy#equal(java.lang.Object, java.lang.Object) 
    14      */
    15     @Override
    16     public boolean equal(Object obj1, Object obj2) {
    17         if (obj1 == null)
    18             return obj2 == null;
    19         if (obj2 == null)
    20             return obj1 == null;
    21         if(obj1.equals(obj2))
    22             return true;
    23         return false;
    24     }
    25 
    26     @Override
    27     public int compare(Object obj1, Object obj2) {
    28         //不晓得怎么写
    29         
    30         return 0;
    31     }
    32 
    33 }
    View Code

      3.3 线性表的链式存储与实现

      3.3.1 单链表

    链表是一系列的存储数据元素的单元通过指针串接起来形成的,因此每个单元至少由两个域,一个域用于数据的存储,另一个域用于指向其他的单元的指针。这里具有一个数据域和多个指针域的存储单元通常称为节点(node)。

     节点的接口Node:

     1 package com.datastructure.chapter03.interfaces;
     2 
     3 public interface Node {
     4     
     5     /** 
     6      * @Title: getData 
     7      * @Description:  获取结点数据域
     8      * @param @return  
     9      * @return Object   
    10      * @throws 
    11      */
    12     public Object getData();
    13     
    14     
    15     /** 
    16      * @Title: setData 
    17      * @Description:  设置节点数据域
    18      * @param @param obj  
    19      * @return void   
    20      * @throws 
    21      */
    22     public void setData(Object obj);
    23     
    24     
    25 }
    View Code

     单链表节点的定义SLNode:

     1 package com.datastructure.chapter03.interfacesImpl;
     2 
     3 import com.datastructure.chapter03.interfaces.Node;
     4 
     5 public class SLNode implements Node {
     6 
     7     
     8     private Object element;
     9     
    10     private SLNode next;
    11     
    12     public SLNode() {
    13         this(null,null);
    14     }
    15     
    16     
    17     public SLNode(Object ele, SLNode next) {
    18         this.element = ele;
    19         this.next = next;
    20     }
    21 
    22 
    23     @Override
    24     public Object getData() {
    25         return element;
    26     }
    27 
    28     @Override
    29     public void setData(Object obj) {
    30         element = obj;
    31     }
    32 
    33 
    34     public SLNode getNext() {
    35         return next;
    36     }
    37 
    38 
    39     public void setNext(SLNode next) {
    40         this.next = next;
    41     }
    42     
    43     
    44     
    45 
    46 }
    View Code

    单链表没有直接前驱,有直接后驱。删除和插入效率较高。

      3.3.2 双向链表

     双向链表节点的定义DLNode:

     1 package com.datastructure.chapter03.interfacesImpl;
     2 
     3 import com.datastructure.chapter03.interfaces.Node;
     4 
     5 public class DLNode implements Node {
     6 
     7     private Object element;
     8     
     9     private DLNode pre;
    10     
    11     private DLNode next;
    12     
    13     
    14     public DLNode() {
    15         this(null,null,null);
    16     }
    17     
    18     public DLNode(Object ele, DLNode pre, DLNode next) {
    19         this.element = ele;
    20         this.pre = pre;
    21         this.next = next;
    22     }
    23 
    24     public DLNode getPre() {
    25         return pre;
    26     }
    27 
    28     public void setPre(DLNode pre) {
    29         this.pre = pre;
    30     }
    31 
    32     public DLNode getNext() {
    33         return next;
    34     }
    35 
    36     public void setNext(DLNode next) {
    37         this.next = next;
    38     }
    39 
    40     @Override
    41     public Object getData() {
    42         return element;
    43     }
    44 
    45     @Override
    46     public void setData(Object obj) {
    47         element = obj;
    48     }
    49 
    50 }
    View Code

       3.3.3线性表的单链表实现

      单链表的实现代码:

      1 package com.datastructure.chapter03.interfacesImpl;
      2 
      3 import com.datastructure.chapter03.exception.OutOfBoundaryException;
      4 import com.datastructure.chapter03.interfaces.List;
      5 import com.datastructure.chapter03.interfaces.Strategy;
      6 
      7 /**
      8  * @ClassName: ListSLinked
      9  * @Description: 单链表的实现
     10  * @author
     11  * @date 2018年3月15日 下午7:26:49
     12  * 
     13  */
     14 public class ListSLinked implements List {
     15 
     16     private Strategy strategy;// 数据元素比较策略
     17 
     18     private SLNode head; // 单链表首节点引用
     19 
     20     private int size; // 线性表中数据元素的个数
     21 
     22     public ListSLinked() {
     23         this(new DefaultStrategy());
     24     }
     25 
     26     public ListSLinked(Strategy strategy) {
     27         this.strategy = strategy;
     28         head = new SLNode();// 头结点
     29         size = 0;
     30     }
     31 
     32     /*
     33      * (非 Javadoc) <p>Title: getSize</p> <p>Description: 获得单链表的长度</p>
     34      * 
     35      * @return
     36      * 
     37      * @see com.datastructure.chapter03.interfaces.List#getSize()
     38      */
     39     @Override
     40     public int getSize() {
     41 
     42         return size;
     43     }
     44 
     45     /*
     46      * (非 Javadoc) <p>Title: isEmpty</p> <p>Description:
     47      * 如果线性表为空返回true,否则返回false</p>
     48      * 
     49      * @return
     50      * 
     51      * @see com.datastructure.chapter03.interfaces.List#isEmpty()
     52      */
     53     @Override
     54     public boolean isEmpty() {
     55 
     56         return size == 0;
     57     }
     58 
     59     /*
     60      * (非 Javadoc) <p>Title: contains</p> <p>Description: 判断线性表中是否包含数据元素e</p>
     61      * 
     62      * @param e
     63      * 
     64      * @return
     65      * 
     66      * @see
     67      * com.datastructure.chapter03.interfaces.List#contains(java.lang.Object)
     68      */
     69     @Override
     70     public boolean contains(Object e) {
     71         SLNode p = head.getNext();
     72         while (p != null) {
     73             if (strategy.equal(p.getData(), e))
     74                 return true;// 遇到第一个包含的就返回true
     75             else
     76                 p = p.getNext();// 否则将p的引用下移一位
     77 
     78         }
     79         return false;
     80     }
     81 
     82     /*
     83      * (非 Javadoc) <p>Title: indexOf</p> <p>Description:获得某个元素线性表中的序号 </p>
     84      * 
     85      * @param e
     86      * 
     87      * @return
     88      * 
     89      * @see
     90      * com.datastructure.chapter03.interfaces.List#indexOf(java.lang.Object)
     91      */
     92     @Override
     93     public int indexOf(Object e) {
     94         SLNode p = head.getNext();
     95         int index = 0;
     96         while (p != null)
     97             if (strategy.equal(p.getData(), e))
     98                 return index;
     99             else {
    100                 index++;
    101                 p = p.getNext();
    102             }
    103         return -1;
    104     }
    105 
    106     /* (非 Javadoc) 
    107      * <p>Title: insert</p> 
    108      * <p>Description: </p> 
    109      * @param i
    110      * @param e
    111      * @throws OutOfBoundaryException 
    112      * @see com.datastructure.chapter03.interfaces.List#insert(int, java.lang.Object) 
    113      */
    114     @Override
    115     public void insert(int i, Object e) throws OutOfBoundaryException {
    116         if (i < 0 || i > size)
    117             throw new OutOfBoundaryException("错误,指定的插入序号越界。");
    118         SLNode p = getPreNode(i);
    119         SLNode q = new SLNode(e,p.getNext());//构造新节点,并且将插入前的前一个节点的后一个节点置于新节点的后面
    120         p.setNext(q);//将前一个节点的下一个节点链接到新节点上
    121         size++;
    122         return ;
    123     }
    124 
    125     /* (非 Javadoc) 
    126      * <p>Title: insertBefore</p> 
    127      * <p>Description: 插入在某个元素之前</p> 
    128      * @param obj
    129      * @param e
    130      * @return 
    131      * @see com.datastructure.chapter03.interfaces.List#insertBefore(java.lang.Object, java.lang.Object) 
    132      */
    133     @Override
    134     public boolean insertBefore(Object obj, Object e) {
    135         SLNode p = getPreNode(obj);
    136         if(p!=null){
    137             SLNode n = new SLNode(e, p.getNext());
    138             p.setNext(n);
    139             size++;
    140             return true;
    141         }
    142         
    143         return false;
    144     }
    145 
    146     
    147 
    148     /* (非 Javadoc) 
    149      * <p>Title: insertAfter</p> 
    150      * <p>Description: 在某个元素后面插入一个元素</p> 
    151      * @param obj
    152      * @param e
    153      * @return 
    154      * @see com.datastructure.chapter03.interfaces.List#insertAfter(java.lang.Object, java.lang.Object) 
    155      */
    156     @Override
    157     public boolean insertAfter(Object obj, Object e) {
    158         SLNode p = head.getNext();
    159         while(p!=null){
    160             if(strategy.equal(p.getData(), obj)){
    161                 SLNode q = new SLNode(e, p.getNext());
    162                 p.setNext(q);
    163                 size++;
    164                 return true;
    165             }else
    166                 p = p.getNext();
    167         }
    168         
    169         return false;
    170     }
    171 
    172     /* (非 Javadoc) 
    173      * <p>Title: remove</p> 
    174      * <p>Description: 删除指定位置的数据元素</p> 
    175      * @param i
    176      * @return
    177      * @throws OutOfBoundaryException 
    178      * @see com.datastructure.chapter03.interfaces.List#remove(int) 
    179      */
    180     @Override
    181     public Object remove(int i) throws OutOfBoundaryException {
    182         
    183         if(i<0||i>size)
    184             throw new OutOfBoundaryException("错误,指定删除序号越界!");
    185         
    186         SLNode p = getPreNode(i);
    187         Object obj = p.getNext().getData();
    188         p.setNext(p.getNext().getNext());
    189         size--;
    190         return obj;
    191     }
    192 
    193     /* (非 Javadoc) 
    194      * <p>Title: remove</p> 
    195      * <p>Description: 删除某一个元素</p> 
    196      * @param e
    197      * @return 
    198      * @see com.datastructure.chapter03.interfaces.List#remove(java.lang.Object) 
    199      */
    200     @Override
    201     public boolean remove(Object e) {
    202         SLNode p = getPreNode(e);
    203         if(p!=null){
    204             p.setNext(p.getNext().getNext());
    205             size--;
    206             return true;
    207         }
    208         return false;
    209     }
    210 
    211     /* (非 Javadoc) 
    212      * <p>Title: replace</p> 
    213      * <p>Description: 替换指定位置的数据元素</p> 
    214      * @param i
    215      * @param e
    216      * @return
    217      * @throws OutOfBoundaryException 
    218      * @see com.datastructure.chapter03.interfaces.List#replace(int, java.lang.Object) 
    219      */
    220     @Override
    221     public Object replace(int i, Object e) throws OutOfBoundaryException {
    222         if(i<0||i>size)
    223             throw new OutOfBoundaryException("错误,指定的序号越界!");
    224         SLNode p = getNode(i);//
    225         Object data = p.getData();
    226         p.setData(e);
    227         return data;
    228     }
    229 
    230     
    231 
    232     /* (非 Javadoc) 
    233      * <p>Title: get</p> 
    234      * <p>Description: 获得指定位置的数据元素</p> 
    235      * @param i
    236      * @return
    237      * @throws OutOfBoundaryException 
    238      * @see com.datastructure.chapter03.interfaces.List#get(int) 
    239      */
    240     @Override
    241     public Object get(int i) throws OutOfBoundaryException {
    242         if(i<0||i>size)
    243             throw new OutOfBoundaryException("错误,指定的序号越界!");
    244         SLNode p = getNode(i);//
    245         return p.getData();
    246     }
    247 
    248     /** 
    249      * @Title: getPreNode 
    250      * @Description:  获得指定位置的前一个节点
    251      * @param @param i
    252      * @param @return  
    253      * @return SLNode   
    254      * @throws 
    255      */
    256     private SLNode getPreNode(int i) {
    257         SLNode p = head;
    258         for (; i > 0; i--)
    259             p = p.getNext();
    260         return p;
    261     }
    262     
    263     
    264     /** 
    265      * @Title: getPreNode 
    266      * @Description:  获得某个数据元素的前一个节点
    267      * @param @param obj
    268      * @param @return  
    269      * @return SLNode   
    270      * @throws 
    271      */
    272     private SLNode getPreNode(Object obj) {
    273         SLNode p = head;
    274         while(p.getNext()!=null){
    275             if(strategy.equal(p.getData(), obj))
    276                 return p;
    277             else
    278                 p = p.getNext();
    279         }
    280         return null;
    281     }
    282     
    283     /** 
    284      * @Title: getNode 
    285      * @Description:  获得指定位置的节点
    286      * @param @param i
    287      * @param @return  
    288      * @return SLNode   
    289      * @throws 
    290      */
    291     private SLNode getNode(int i) {
    292         SLNode p = head.getNext();
    293         for(;i>0;i--) p = p.getNext(); 
    294         return p;
    295     }
    296 
    297 }
    View Code

     getPreNode(Object e)、getPreNode(int i),这两个防范的平均运行时间T(n)≈n/2。

    replace(int i,Object e)、get(int i)算法的平均运行时间T(n)≈n/2。比数组慢

    insert(int i,Object e)、remove(int i),平均运行时间T(n)≈n/2。与使用数组实现的运行时间相同。

    insertBefore(Object obj,Object e)、insertAfter(IObject obj,Object e),remove(Object e),平均运行时间T(n)≈n/2<n,要由于使用数组实现的运行时间。

        3.4 两种实现的对比

      3.4.1基于时间的比较

       线性表的基本操作查找、插入、删除

     查找:基于序号的查找,数组是随机存储的,线性表的顺序存储可以在常数时间内完成;而在链式存储中由于需要从头结点开始顺着链表才能取得,无法在常数时间内完成,因此顺序存储优于链式存储。查找还有基于元素的查找,而顺序存储和链式存储在这种情况先军事从线性表中序号为0的元素开始查找,因此两种实现性能相同。若是,在线性表的使用中主要操作是查找,那么应当选用顺序存储实现线性表。

       插入、删除:基于数据元素的操作,对于数组而言,首先顺序查找定位相应数据元素,然后才能插入,删除,并且在插入、删除郭晨又要移动大量元素;而链表在定位数据元素的基础上,只需要修改指针就可以了,效率要高。基于序号的操作,顺序存储中平均需要移动一半的数据;链式存储中不能直接定位,平均比较一般的元素才能定位。因此,二者,效率相当。但综合起来,链式增删好些。

      3.4.2基于空间的比较

     当数据较大时,顺序存储的线性表由于动态扩展出的存储空间被大量空闲,利用率不高;而链式不存在这种情况,所以数据量大的时候,宜用链式。

    当数元素结构简单,且数据量小的时候,链式由于用额外的空间来表示数据元素之间的逻辑关系。所以开销较大。此时,顺序存储较好。

  • 相关阅读:
    python入门6 字符串拼接、格式化输出
    python入门5 运算符
    python入门3 python变量,id(),is运算符
    python入门2 python字符串换行显示、字符串太长连接多行
    python入门1 python手动编译py_compile,compileall
    测试笔记:jsonp跨域接口测试
    Jmeter入门16 数据构造之随机数Random Variable & __Random函数
    Jmeter入门15 JSON Assertion 适用于json格式的响应断言
    openshift 配置ldap认证
    openshift node资源限制
  • 原文地址:https://www.cnblogs.com/huaxueyihao/p/8519983.html
Copyright © 2020-2023  润新知