线性表是一种按顺序储存数据是的常用结构,大多数的线性表都支持以下的典型操作:

从线性表提取插入删除一个数据;

找出线性表中的某一个元素;

找出线性表中的元素;

确定线性表中是否包含某一个元素,确定线性表是否为空;

实现线性表的方法有两种:

1、数组(arry),数组是动态的创建的,如果元素超过了数组的容量,就会创建一个新的数组并且把当前的数组元素复制到更大的数组里;

2、连式结构(linked structure)。连式结构有节点构成,节点是动态创建的。

方便起见,把数组称为MyArrayList,把连式结构称为MylinkedList,他们有相同的操作,却有这不同的实现。

设计一个好用的线性表,通常把一些通用的操作归纳为一个接口和抽象类,抽象类提供接口实现的框架,以更好地实现接口。把这样的接口叫MyList,把这样的抽象类叫MyAbstractList。

以下是接口MyList的代码:

public interface MyList<E> {
public void add(E e);
public void add(int index,E e);
public void clear(); //清除所有元素
public boolean contains(E e);
public E get(int index);
public int indexOf(E e);
public boolean isEmpty();
public int lastIndexOf(E e);
public boolean remove(E e);
public E remove(int index); //删除指定元素
public Object set(int index, E e); //在指定位置插入元素
public int size();
}

下面是MyAbstractList代码(实现了各方法):

public abstract class MyAbstractList<E> implements MyList<E> {
protected int size = 0; //声明size protected MyAbstractList(){}
protected MyAbstractList(E[] objects){
for(int i = 0;i<objects.length;i++){
add(objects[i]);
}
}
public void add(E e){
add(size,e);
}
public boolean isEmpty(){
return size==0; }
public int size(){
return size;
}
public boolean remove(E e){
if(indexOf(e) >=0){
remove (indexOf(e));
return true;
}
else
return false;
}
}

下面先讲数组的线性表示:

数组是一种固定大小的数据结构,一旦创建就无法改变,但仍然可以用数组来实现动态的数据结构,方法是当数组大小不够用的时候,就创建一个更大的数组类来替换当前数组。

初始状态时,默认大小,创建一个类型为E[ ] 的数组data。向数组中插入一个新的元素时,首先确认数组是否有足够的空间,若不够,则创建一个为当前数组两倍的数组,然后复制元素到新的数组里面。现在在指定的下标处插入新的元素,并且要将指定下标后面的所有元素的下标都增加一。若是删除元素,则要把后面元素下标都减少一。

大体思路是:

+ MyArrayList()   创建默认数组

+MyArrayList(E[ ] objects)   由对象数组创建一个数组

—ensureCapacity()    如果需要就扩大数组

+trimToSize()    将数组大小缩小至线性表的当前大小

下面是MyArrayList实现MyAbstractList的代码:

public class MyArrayList<E> extends MyAbstractList<E> {
public static final int INITIAL_CAPACITY = 16; //定义初始容量
private E[] data = (E[])new Object[INITIAL_CAPACITY]; //创建默认数组
public MyArrayList() {
} //由对象数组创建一个数组
public MyArrayList(E[] objects) {
for (int i = 0; i < objects.length; i++)
add(objects[i]); // Warning: don抰 use super(objects)!
} //在指定下标处增加元素
public void add(int index, E e) {
//如果需要调用数组增加两倍的方法
ensureCapacity(); // 把指定下标后面的数的下标全部加一
for (int i = size - 1; i >= index; i--)
data[i + 1] = data[i];
data[index] = e;
size++;
} //如果需要,数组增加两倍的方法
private void ensureCapacity() {
if (size >= data.length) {
E[] newData = (E[])(new Object[size * 2 + 1]);
System.arraycopy(data, 0, newData, 0, size);
data = newData;
}
}
//清空元素
public void clear() {
data = (E[])new Object[INITIAL_CAPACITY];
size = 0;
} //是否包含某一元素的方法
public boolean contains(E e) {
for (int i = 0; i < size; i++)
if (e.equals(data[i])) return true; return false;
} //给定下标,获得下标所指定的元素
public E get(int index) {
return data[index];
} //从第一个元素开始搜索某一元素 ,有则返回下标值,否则返回-1
public int indexOf(E e) {
for (int i = 0; i < size; i++)
if (e.equals(data[i])) return i; return -1;
} //从最后一个元素开始
public int lastIndexOf(E e) {
for (int i = size - 1; i >= 0; i--)
if (e.equals(data[i])) return i; return -1;
} //删除元素
public E remove(int index) {
E e = data[index]; for (int j = index; j < size - 1; j++)
data[j] = data[j + 1]; //最后一个元素为空
data[size - 1] = null;
size--;
return e;
} //替换
public E set(int index, E e) {
E old = data[index];
data[index] = e;
return old;
} //重写Object中的方法,返回一个表示包含数组中全部元素的字符串
public String toString() {
StringBuilder result = new StringBuilder("["); for (int i = 0; i < size; i++) {
result.append(data[i]);
if (i < size - 1) result.append(", ");
} return result.toString() + "]";
} //将数组大小缩小至线性表的当前大小
public void trimToSize() {
if (size != data.length) {
E[] newData = (E[])(new Object[size]);
System.arraycopy(data, 0, newData, 0, size);
data = newData;
}
}
}

测试的一个事例:

public class TestList {
public static void main(String[] args) {
//创建一个线性表
MyList<String> list = new MyArrayList<String>(); //加入一个元素
list.add("喜欢");
list.add(0,"我");
list.add("你");
System.out.println(list); list.add(1,"非常");
list.add(1,"很");
System.out.println(list); list.remove(1);
System.out.println(list); list.set(3, "你 ,爱你一万年");
System.out.println(list); }
}

再来讲链表:

由于MyArrayList是有数组实现的,在使用get()、set函数会是  高效的,但是在用add()和remove时效率却并不高,因为可能要移动大量的元素。为提高效率,可以采用链式结构来实现线性表。东西有点多,写到笔记二去吧。

java线性表学习笔记(一)的更多相关文章

  1. java线性表学习笔记(二)

    链表中的每一个元素都包含一个称为节点的结构,每向链表中增加一个元素,就会产生一个与之相关的节点,每个节点与它相邻的节点相连接(这是基础吧,不过在看c的时候没认真看,呼). 定义节点类如下(使用了泛型, ...

  2. 《深入理解Java虚拟机》学习笔记

    <深入理解Java虚拟机>学习笔记 一.走近Java JDK(Java Development Kit):包含Java程序设计语言,Java虚拟机,JavaAPI,是用于支持 Java 程 ...

  3. java之jvm学习笔记三(Class文件检验器)

    java之jvm学习笔记三(Class文件检验器) 前面的学习我们知道了class文件被类装载器所装载,但是在装载class文件之前或之后,class文件实际上还需要被校验,这就是今天的学习主题,cl ...

  4. java之jvm学习笔记十三(jvm基本结构)

    java之jvm学习笔记十三(jvm基本结构) 这一节,主要来学习jvm的基本结构,也就是概述.说是概述,内容很多,而且概念量也很大,不过关于概念方面,你不用担心,我完全有信心,让概念在你的脑子里变成 ...

  5. 《深入理解 Java 虚拟机》学习笔记 -- 内存区域

    <深入理解 Java 虚拟机>学习笔记 -- 内存区域 运行时数据区域 主要分为 6 部分: 程序计数器 虚拟机栈 本地方法栈 Java 堆 方法区 如图所示: 1. 程序计数器(线程私有 ...

  6. JAVA GUI编程学习笔记目录

    2014年暑假JAVA GUI编程学习笔记目录 1.JAVA之GUI编程概述 2.JAVA之GUI编程布局 3.JAVA之GUI编程Frame窗口 4.JAVA之GUI编程事件监听机制 5.JAVA之 ...

  7. Java多线程技术学习笔记(二)

    目录: 线程间的通信示例 等待唤醒机制 等待唤醒机制的优化 线程间通信经典问题:多生产者多消费者问题 多生产多消费问题的解决 JDK1.5之后的新加锁方式 多生产多消费问题的新解决办法 sleep和w ...

  8. Java安全防御学习笔记V1.0

    Java安全防御学习笔记V1.0http://www.docin.com/p-766808938.html

  9. Java线性表的排序

    Java线性表的排序 ——@梁WP 前言:刚才在弄JDBC的时候,忽然觉得order-by用太多了没新鲜感,我的第六感告诉我java有对线性表排序的封装,然后在eclipse里随便按了一下“.” ,哈 ...

随机推荐

  1. 深入理解Java对象的序列化与反序列化的应用

    当两个进程在进行远程通信时,彼此可以发送各种类型的数据.无论是何种类型的数据,都会以二进制序列的形式在网络上传送.发送方需要把这个Java对象转换为字节序列,才能在网络上传送:接收方则需要把字节序列再 ...

  2. POJ 3693 (后缀数组) Maximum repetition substring

    找重复次数最多的字串,如果有多解,要求字典序最小. 我也是跟着罗穗骞菊苣的论文才刷这道题的. 首先还是枚举一个循环节的长度L,如果它出现两次的话,一定会包含s[0], s[L], s[2L]这些相邻两 ...

  3. (转载) jQuery 页面加载初始化的方法有3种

    jQuery 页面加载初始化的方法有3种 ,页面在加载的时候都会执行脚本,应该没什么区别,主要看习惯吧,本人觉得第二种方法最好,比较简洁. 第一种: $(document).ready(functio ...

  4. UIView的user Interaction Enabled属性

    A Boolean value that determines whether user events are ignored and removed from the event queue. 译: ...

  5. JAVA 日志管理

    http://www.360doc.com/content/10/0704/05/2017726_36768082.shtml http://javacrazyer.iteye.com/blog/11 ...

  6. 内核打上yaffs2补丁遇到的问题

    移植yaffs2文件系统时,首先要在内核中添加对yaffs2的支持,使用命令:./patch-ker.sh c 内核目录时,出现下面错误: usage:  ./patch-ker.sh  c/l m/ ...

  7. setTimeout/setInterval

    //使用 setTimeout 时需注意,当该代码执行时,JS 会立即编译函数第一个参数“code” //所以该函数的第一个参数应该为:需要编译的代码.或者一个函数 //例1:setTimeout(& ...

  8. 【英语】Bingo口语笔记(31) - Bring系列

    bring up 表示在哪长大 要用被动形式 BYOB 请自带酒瓶

  9. 【转】搭建Python的Eclipse开发环境之安装PyDev插件--离线安装

    原文网址:http://blog.csdn.net/wangpingfang/article/details/7181223 使用update site安装pydev插件 注意:该安装指南针对ecli ...

  10. Oracle 11g RAC oc4j/gsd Offline

    Oracle 11g RAC中,发现oc4j以及gsd服务都处于offline状态,这是Oracle 11g RAC默认情形.即便如此,并不影响数据库的使用,因为 oc4j 是用于WLM 的一个资源, ...