顺序表的设计与实现List(Arraylist)

Posted on 2017-09-09 23:22  想念熊  阅读(813)  评论(0)    收藏  举报
  1 package com.tmx.sequence;
  2 
  3 //采用线性表实现一个list集合
  4 public class SeqList<T> extends Object {
  5     private Object[] elements;  // 数组
  6     private int n;                 // 长度
  7 
  8     /**
  9      * 构造方法,根据传参创建空表
 10      * @param length
 11      */
 12     public SeqList(int length) {
 13         this.elements = new Object[length];
 14         this.n = length;
 15     }
 16 
 17     /**
 18      * 空参构造将会调用本类已声明的指定参数列表的构造方法 进而创建一个空表,默认长度为64
 19      */
 20     public SeqList() {
 21         this(64);
 22     }
 23 
 24     /**
 25      * 重载构造方法,根据传参确定表长度,并且将数组元素复制到成员变量elements中
 26      * @param values
 27      */
 28     public SeqList(T[] values) {
 29         this(values.length); // 创建容量为values.length的空表
 30         for (int i = 0; i < values.length; i++) {
 31             this.elements[i] = values[i]; // 复制数组元素
 32             this.n = elements.length;
 33         }
 34     }
 35 
 36     /**
 37      * 判断顺序表是否为空,为空则返回true,时间复杂度为O(1)
 38      * @return
 39      */
 40     public boolean isEmpty() {
 41         return this.n == 0;
 42     }
 43 
 44     /**
 45      * 返回顺序表元素个数,时间复杂度为O(1)
 46      * @return
 47      */
 48     public int size() {
 49         return this.n;
 50     }
 51 
 52     /**
 53      * 返回第i个元素,若i越界则返回null,,时间复杂度为O(1)
 54      * @param i
 55      * @return
 56      */
 57     @SuppressWarnings("unchecked")
 58     public T get(int index) {
 59         if (index >= 0 && index < this.n) {
 60             return (T) this.elements[index];
 61         } else {
 62             return null;
 63         }
 64     }
 65 
 66     /**
 67      * 替换指定位置的元素,若index越界,则抛出越界异常,若x为空,则抛出空对象异常,时间复杂度为O(1)
 68      * @param index
 69      * @param x
 70      */
 71     public void set(int index, T x) {
 72         if (x == null) {
 73             throw new NullPointerException("x==null");
 74         }
 75         if (index >= 0 && index < this.n) {
 76             this.elements[index] = x;
 77         } else {
 78             throw new java.lang.IndexOutOfBoundsException(index + "");
 79         }
 80     }
 81 
 82     /**
 83      * 覆写Object的toString 方法,需要遍历,时间复杂度为O(n)
 84      */
 85     public String toString() {
 86         String str = this.getClass().getName() + "(";
 87         if (this.n > 0) {
 88             str += this.elements[0].toString();
 89         }
 90         for (int i = 0; i < this.n; i++) {
 91             str += "," + this.elements[i].toString();
 92         }
 93         return str + ")";
 94     }
 95 
 96     /**
 97      * 在指定位置插入操作,index是插入的位置(下标),x是插入的元素
 98      * @param index
 99      * @param x
100      * @return
101      */
102     public int add(int index, T x) {
103         if (x == null) {
104             throw new NullPointerException("x==null");
105         }
106         // 对index进行容错处理,使下标index始终在数组长度范围内
107         if (index < 0) {
108             index = 0;
109         }
110         if (index > this.n) {
111             index = this.n;
112         }
113         // 复制原数组到一个新的数组source中
114         Object[] source = this.elements;
115         // 如数组满,则扩充顺序表的数组容量,通过重申请和复制完成
116         if (this.n == elements.length) {
117             this.elements = new Object[source.length + 1];
118             // 复制当前数组前i-1个元素到新的数组中
119             for (int j = 0; j < index; j++) {
120                 this.elements[j] = source[j];
121             }
122         }
123         // x插入为第i个元素
124         this.elements[index] = x;
125         // 从i开始至表尾的元素往后移,次序从后向前,这些元素的下标都要加1
126         for (int j = this.n - 1; j >= index; j--) {
127             this.elements[j + 1] = source[j];
128         }
129         // 数组的长度增加
130         this.n++;
131         // 返回插入元素的下标
132         return index;
133     }
134 
135     /**
136      * 重载add方法,在尾部插入元素
137      * @param x
138      * @return
139      */
140     public int add(T x) {
141         return this.add(this.n, x);
142     }
143 
144     /**
145      * 在尾部插入一个线性表对象
146      * @param newList
147      * @return
148      */
149     public int addAll(SeqList<T> newList) {
150         Object[] source = this.elements;
151         this.n = source.length + newList.size();
152         // 数组扩容
153         this.elements = new Object[n];
154         // 将原数组的元素拷贝到新数组中
155         for (int i = 0; i < source.length; i++) {
156             this.elements[i] = source[i];
157         }
158         // 将插入的集合元素拷贝到数组的后面
159         for (int j = 0; j < newList.size(); j++) {
160             this.elements[source.length + j] = newList.get(j);
161         }
162         return n;
163     }
164 
165     /**
166      * 从指定位置index处开始插入一组元素
167      * @param index
168      * @param newList
169      * @return
170      */
171     public int addAll(int index, SeqList<T> newList) {
172         // 对index进行容错处理,使下标index始终在数组长度范围内
173         if (index < 0) {
174             index = 0;
175         }
176         if (index > this.n) {
177             index = this.n;
178         }
179         // 复制原数组到一个新的数组source中
180         Object[] source = this.elements;
181         this.n = source.length + newList.size();
182         this.elements = new Object[n];
183         // 从source中拷贝index之前的元素
184         for (int j = 0; j < index; j++) {
185             this.elements[j] = source[j];
186         }
187         // 从集合中取出元素拷贝到新数组中
188         for (int j = 0; j < newList.size(); j++) {
189             this.elements[j + index] = newList.get(j);
190         }
191         // 从source中拷贝index之后的元素
192         for (int j = index; j < source.length; j++) {
193             this.elements[j + newList.size()] = source[j];
194         }
195         return n;
196     }
197 
198     /**
199      * 删除元素,返回被删除元素,index之后的元素都要往前移一位
200      * @param index
201      */
202     @SuppressWarnings("unchecked")
203     public T remove(int index) {
204         T old = null;
205         if (index > this.n) {
206             index = this.n - 1;
207         }
208         if (index >= 0 && index < this.n) {
209             old = (T) this.elements[index]; // 被删除元素
210         }
211         // 复制原数组到source作为备份
212         Object[] source = this.elements;
213         // 前i个元素复制
214         for (int j = 0; j < index; j++) {
215             this.elements[j] = source[j];
216         }
217         // 后i个朝前挪一位
218         for (int j = index; j < this.n - 1; j++) {
219             this.elements[j] = source[j + 1];
220         }
221         this.n--;
222         return old;
223     }
224 
225     /**
226      * 查找指定元素的位置,若不存在则返回-1
227      * @param value
228      * @return
229      */
230     public int indexOf(T value) {
231         for (int i = 0; i < this.n; i++) {
232             if (value.equals(this.elements[i])) {
233                 return i;
234             }
235         }
236         return -1;
237     }
238 
239     /**
240      * 顺序表比较相等 (non-Javadoc)
241      */
242     public boolean equals(Object obj) {
243         // 同一个顺序表实例
244         if (this == obj) {
245             return true;
246         }
247         // SeqList<?>是所有SeqList<T>的父类
248         if (obj instanceof SeqList<?>) {
249             SeqList<T> slist = (SeqList<T>) obj;
250             if (this.n == slist.n) {
251                 for (int i = 0; i < this.n; i++) {
252                     if (!this.get(i).equals(slist.get(i))) {
253                         return false;
254                     }
255                     return true;
256                 }
257             }
258         }
259         return false;
260     }
261 }