您的位置:首页 > 编程语言 > Java开发

java学习笔记4>顺序线性表的实现及其内存分配

2014-03-21 21:19 701 查看
相信大家用过很多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的实现,如果有不正确的地方希望大家指点指点
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息