相信大家用过很多java提供的集合类,如list,map,set等,而对于线性表这种数据结构,我们用得最多的就是实现了java.util.List这个接口的ArrayList类和LinkedList类
ArrayList类就是线性表的顺序表示的实现,如果大家度过该类的源代码就能很清楚的看到顺序线性表是如何在java中实现的了
相信大家都很清楚线性表这种数据结构
线性表的基本操作:
>初始化一个空的线性表
>获取线性表的长度
>获取线性表中指定索引处的元素
>返回线性表中指定元素的索引,否则返回-1
>向指定位置插入元素
>直接插入元素在表中的末尾
>直接删除表中的末尾元素
>删除指定位置的元素
>判断表是否为空
以下程序引用自《java程序员的基本修养》,修改了部分函数名和纠正了一些注释,该类实现了一个简单的顺序线性表
import java.util.Arrays;
public class SequenceList<T> {
private int DEFAULT_SIZE = 16;
//保存数组的长度
private int capacity;
//定义一个数组用于保存顺序线性表的元素
private Object[] elementData;
//保存当前数组的元素个数
private int size=0;
//以默认数组长度创建空顺序线性表
public SequenceList(){
capacity = DEFAULT_SIZE;
elementData = new Object[capacity];
}
//以一个初始话元素来创建顺序线性表
public SequenceList(T element){
this();
elementData[0]=element;
size++;
}
/**
* 以指定长度的数组来创建顺序线性表
* @param element 指定顺序线性表中的第一个元素
* @param initSize 指定顺序线性表底层数组的长度
*/
public SequenceList(T element,int initSize){
capacity = 1;
//把capacity设为大于initSize的最小的2的n次方
while(capacity<initSize){
capacity <<=1;
}
elementData = new Object[capacity];
elementData[0] = element;
size++;
}
//获取顺序线性表的大小
public int length(){
return size;
}
//获取顺序线性表中索引为i处的元素
@SuppressWarnings("unchecked")
public T get(int i){
if( i<0 || i>size-1 ){
throw new IndexOutOfBoundsException("线性表索引越界");
}
return (T) elementData[i];
}
//查找顺序线性表中指定元素的索引,有则返回,无则返回-1
public int getIndexByElement(T element){
for(int i=0;i<size;i++){
if(elementData[i].equals(element)){
return i;
}
}
return -1;
}
//向顺序线性表的指定位置插入一个元素
public void insert(T element,int index){
if(index<0||index>size){
throw new IndexOutOfBoundsException("线性表索引越界");
}
ensureCapacity(size+1);
//将index以后的所有元素向后移动一格
System.arraycopy(elementData, index, elementData, index+1, size-index );
elementData[index]=element;
size++;
}
//在线性表的末尾添加一个元素
public void add(T element){
insert(element, size);
}
//扩充底层数组长度,此方法性能很差
public void ensureCapacity(int minCapacity){
//如果数组原来的长度小于目前所需长度
if(capacity<minCapacity){
while(capacity<minCapacity){
capacity <<=1;
}
elementData = Arrays.copyOf(elementData, capacity);
}
}
//删除顺序线性表中指定索引处的元素
@SuppressWarnings("unchecked")
public T delete(int index){
if(index<0||index>size-1){
throw new IndexOutOfBoundsException("线性表索引越界");
}
T oldValue = (T)elementData[index];
int numMoved = size-index-1;
if(numMoved>0){
System.arraycopy(elementData, index+1, elementData, index, numMoved);
}
//清空最后一个元素
elementData[--size]=null;
return oldValue;
}
//删除顺序线性表中最后一个元素
public T remove(){
return delete(size-1);
}
//判断顺序线性表是否为空表
public boolean empty(){
return size==0;
}
//清空顺序线性表
public void clear(){
Arrays.fill(elementData, null);
size=0;
}
public String toString(){
if(size==0){
return "[]";
}else{
StringBuilder sb =new StringBuilder("[");
for(int i=0;i<size;i++){
sb.append(elementData[i].toString()+",");
}
int len = sb.length();
return sb.delete(len - 1, len).append("]").toString();
}
}
}
测试线性表
public class TestSequenceList {
public static void main(String[] args){
SequenceList<String> list = new SequenceList<String>("first",6);
list.add("second");
list.add("third");
list.insert("forth",3);
list.insert("fifth",2);
list.delete(1);
System.out.println(list);
System.out.println("fifth在顺序线性表中的位置:"+list.getIndexByElement("fifth"));
}
}
输出结果:
该线性表在内存中的分配情况如下:
由于初始化时是
SequenceList<String> list = new SequenceList<String>("first",6);
因此经过计算,初始化数组的长度是8,size为1
故内存分配如上图所示
以上就是本次介绍的内容,下次继续跟大家分享LinkedList的实现,如果有不正确的地方希望大家指点指点