第1关:顺序表的实现之增删功能
300
- 任务要求
- 参考答案
- 评论62
任务描述
本关任务:实现一个顺序表,并实现增加元素,删除元素功能。
相关知识
顺序表
顺序表是在计算机内存中以数组的形式保存的线性表,线性表的顺序存储是指用一组地址连续的存储单元依次存储线性表中的各个元素、使得线性表中在逻辑结构上相邻的数据元素存储在相邻的物理存储单元中,即通过数据元素物理存储的相邻关系来反映数据元素之间逻辑上的相邻关系,采用顺序存储结构的线性表通常称为顺序表。
顺序表是将表中的结点依次存放在计算机内存中,一组地址连续的存储单元中。
下图是一个顺序表示意图:
增加元素
现要插入元素到顺序表中,若没有指定添加元素的位置,则元素直接添加到数组末尾,表元素个数加1
。
如指定要插入到位置index
,则下标为index
及之后的元素都需相应的移动。
现假设表中已有元素15 23 46 16 57 10 64
,要插入一个新元素48
到位置3
(即调用list.Add(3,48)
方法),因这里下标为3
的元素是16
,则16
及之后的元素都需移动。
表中元素的变化过程如下图:
删除元素
同样,假设现在表中已有元素15 23 46 16 57 10 64
,现要删除下标为3
的元素,即调用list.remove(3)
方法,则表中元素的变化过程如下图:
Java 数组
数组,是由相同类型的元素的集合所组成的数据结构,分配一块连续的内存来存储。你可以声明一个数组变量,如 arr[10]
来代替直接声明 10
个独立变量 arr0
,arr1
,....,arr9
。
声明数组变量
首先必须声明数组变量,才能在程序中使用数组。下面是声明数组变量的语法:
Type[] arrVar; // 方式一
Type arrVar[]; // 方式二
这两种声明数组的方式都是正确的。 例如,声明一个double
型数组,我们可以这样写:
double[] myArr
或者
double myArr[]
创建数组
Java
语言使用new
操作符来创建数组,如下:
myArr = new Type[arrSize];
arrSize
是数组的大小,所以这里我们创建了一个大小为arrSize
的Type
类型的数组,并把它赋值给myArr
。
数组变量的声明、创建数组可以用一条语句完成,如下:
Type[] arrVar = new Type[arrSize];
Java 中的数组下标
在Java
中,数组的下标是从0
开始的。如一个有7
个元素的数组,其下标范围是0,1,2,3,4,5,6
。
我们实现的表中,下标仍然是从0
开始,即list.get(0)
返回的是第一个元素,list.get(n-1)
返回的是第n
个元素。
编程要求
本关的编程任务是补全右侧代码片段中所有Begin
至End
中间的代码,具体要求如下:
- 向表中添加元素;
- 向表中指定位置添加元素;
- 删除指定位置的元素并返回被删除的元素。
具体请参见后续测试样例。
本关涉及的代码文件MyArrayList.java
的代码框架如下:(解答过程)
package step1;
/**
* Created by zengpeng on 2018/1/6.
*/
public class MyArrayList {
private int[] elements;//元素
private int size;//List中当前的元素个数
public MyArrayList() {
this(1);//List默认大小为1
}
/**
* 按指定大小capacity构造List
*
* @param capacity List初始化时的大小
*/
public MyArrayList(int capacity) {
elements = new int[capacity];
size = 0;
}
/**
* 返回List中元素的个数
*
* @return
*/
public int size() {
return size;
}
/**
* 添加一个元素到末尾
*
* @param item
*/
public void Add(int item) {
int len = elements.length;
if (size == len - 1) {
resize(2 * len);
}
elements[size++] = item;
}
/**
* 添加一个元素到指定位置index
*
* @param index
* @param item
*/
public void Add(int index, int item) {
validateRangeForAdd(index);
int len = elements.length;
if (size == len - 1) {
resize(2 * len);
}
for (int i = size; i > index; i--) {
elements[i] = elements[i - 1];
}
elements[index] = item;
size++;
}
/**
* 删除指定位置index的元素,并返回被删除的元素
*
* @param index
* @return 被删除的元素
*/
public int remove(int index) {
validateRange(index);
int oldVal = elements[index];
for (int i = index; i < size - 1; i++) {
elements[i] = elements[i + 1];
}
--size;
return oldVal;
}
/**
* 返回表中下标为index的元素
*
* @param index 下标
* @return
*/
public int get(int index) {
validateRange(index);
/********** Begin *********/
return index;//(特别注意 一定要返回值 智科01)
/********** End *********/
}
/**
* 校验索引范围
*
* @param index
*/
private void validateRange(int index) {
if (index >= size || index < 0) {
throw new ArrayIndexOutOfBoundsException("索引越界了哦!Index: " + index + ", Size: " + size);
}
}
/**
* 校验索引范围
*
* @param index
*/
private void validateRangeForAdd(int index) {
if (index > size || index < 0)
throw new IndexOutOfBoundsException("索引越界了哦!Index: " + index + ", Size: " + size);
}
/**
* 动态扩展数组大小
*
* @param capacity
*/
private void resize(int capacity) {
assert capacity > size;
int[] tmp = new int[capacity];
for (int i = 0; i < size; i++) {
tmp[i] = elements[i];
}
elements = tmp;
}
}