线性表
线性表(linear list)是n个具有相同特性的数据元素的有限序列。线性表是一种在实际中广泛使用的数据结构.
常见的线性表有:顺序表、链表、栈、队列、字符串...
线性表在逻辑上是线性结构,也就是连续的一条直线;但在物理结构上并不一定是连续的。
因为线性表在物理存储时,通常以数组和链式结构的形式存储。
(线性表在逻辑上连续,在物理结构上不一定连续)
顺序表
顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储。在数组上完成数据的增删改查。
顺序表一般可以分为:(借助数组实现)
1.静态顺序表:使用定长数组存储
2.动态顺序表:使用动态开辟的数组存储
顺序表:
分析:如何判断下图中的有效数据,对于顺序表来说,先给其增加一个域。在这个域中,放的是有效数据(usedSize),每当存放一个数据usedSizd++,我们需要运用java的OOP(面向对象)思想来实现
先抽象一个类,类中所对应的属性,方法。成员方法有插入、删除、增删改查。
图解:
首先定义一个名为ISequence的接口:
将如下对应的属性写入:
public abstract class ISequence {
//在pos位置插入val
public abstract boolean add(int pos, Object data);
//查找关键字key 找到返回key的下标,没有返回null;
public abstract int search(Object key);
//查找是否包含关键字key是否在顺序表当中(这个和search有点冲突)
public abstract boolean contains(Object key);
//得到pos位置的值
public abstract Object getPos(int pos);
//删除第一次出现的关键字key
public abstract Object remove(Object key);
//得到顺序表的长度
public abstract int size();
//打印顺序表
public abstract void display();
//清空顺序表以防内存泄漏
public abstract void clear();
实现以上接口,定义一个类MySequenceImpl:
//在MySequenceImpl中
/*Description:顺序表的实现*/
public class MySequenceImpl implements ISequence{
private static final int DEFAULT_SIZE = 10;
private Object[] elem;
private int usedSize;//有效数据个数
public MySequenceImpl(){//无参构造
this.elem = new Object[DEFAULT_SIZE];
this.usedSize = 0;
}
private boolean isFull(){
/*if(this.usedSize == this.elem.length){
return true;
}
return false;*/
return this.usedSize == this.elem.length;
}
//在pos位置插入val
public boolean add(int pos, Object data) {
//1.pos位置的合法性进行判断
if(pos < 0 || pos > this.usedSize){ // 不合法
return false;
}
//2.判断是否为满。
if(isFull()) {
//2倍扩容
//System.arraycopy();
this.elem = Arrays.copyOf(this.elem,
2 * this.elem.length);
}
for(int i = this.usedSize-1;i >= pos; i--){ //从后往前移动
this.elem[i+1] = this.elem[i];
}
this.elem[pos] = data;
this.usedSize++;
return true;
}
//判断顺序表是否为空
private boolean isEmpty(){
return this.usedSize == 0;
}
@Override
public int search(Object key) {
if(isEmpty()){
return -1;
}
//遍历数组找key,遍历时取决于usedSize
for (int i = 0; i< this.usedSize; i++){
if(this.elem[i].equals(key)){
return i;
}
}
return -1;
}
public boolean contains(Object key) {
if(isEmpty()){
return false;
}
//遍历数组找key,遍历时取决于usedSize
for (int i = 0; i< this.usedSize; i++){
if(this.elem[i].equals(key)){
return true;
}
}
return false;
}
public Object getPos(int pos) {
if (pos < 0 || pos >= this.usedSize){
return null;
}
return this.elem[pos];
}
public Object remove(Object key) {
int index = search(key);
if(index == -1){
return null;
}
Object data = this.elem[index];
int i ;
for (i = index; i< this.usedSize-1; i++){
this.elem[i] = this.elem[i+1];
}
this.usedSize--;
this.elem[i+1] = null;
return data;
}
public int size() {
return this.usedSize;
}
public void display() {
for(int i = 0;i <this.usedSize;i++){
System.out.println(this.elem[i]+"");
}
System.out.println();
}
public void clear() {
//如何测试内存泄漏
for (int i = 0; i < this.usedSize; i++){
this.elem[i] = null;
}
}
}
测试一下:
public class TestDemol {
public static void main(String[] args){
MySequenceImpl mySequence = new MySequenceImpl();
for (int i = 0 ;i < 20; i++){
mySequence.add(i,i);
}
mySequence.display();
Object res = mySequence.remove(8);
System.out.println(res);
mySequence.display();
}
}