提示:以下是本篇文章正文内容,Java系列学习将会持续更新
一、什么是线性表
基本概念
线性表(linear list)是n个元素彼此之间逻辑连续的有限序列。 线性表是一种在实际中广泛使用的数据结构。
常见的线性表:顺序表、链表、栈、队列、字符串…
线性表在逻辑上是线性结构,也就说是连续的一条直线。
但在物理存储时,分为两种形式:
数组:顺序表(元素不仅逻辑连续,物理上也连续)
链式结构:元素之间仅仅是逻辑连续
图解
二、顺序表(动态数组)
基本概念
顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构。是基于数组的线性表,一般情况下采用数组存储。在数组上完成数据的增删查改。
顺序表一般可以分为:
静态顺序表:使用定长数组存储。
动态顺序表:使用动态开辟的数组存储。
代码实现
import java.util.Arrays;
/**
* 基于数组的顺序表
*/
public class MyArray {
private int[] data;
private int size = 0;
//构造方法
public MyArray(){
data = new int[10];
}
public MyArray(int l){
data = new int[l];
}
/** 增加 Create ****************************/
//尾插元素
public void addLast(int num){
addIndex(size,num);
}
//头插元素
public void addFirst(int num){
addIndex(0,num);
}
//中间插入元素
public void addIndex(int index,int num){//在第index个元素后插入num元素
if(index<0||index>size){
System.err.println("add index illegal!");
return ;
}
if(size == data.length)
grow();
for(int i=size;i>index;i--){
data[i] = data[i-1];
}
data[index] = num;
size++;
}
/** 查找 Read ****************************/
//返回元素的索引号
public int indexOf(int num){
for(int i=0;i<size;i++){
if(data[i] == num){
return i;
}
}
return -1; //没有该元素
}
//判断是否有该元素
public boolean contains(int num){
if(indexOf(num) == -1)
return false;
else
return true;
}
//返回索引处的元素
public int get(int index){
if(index<0||index>=size){
System.err.println("get index illegal!");
return -1;
}
else
return data[index];
}
/** 修改 Update ****************************/
public void set(int index,int num){ //修改索引在index处的元素
if(index<0||index>=size){
System.err.println("set index illegal!");
return ;
}
data[index] = num;
}
/** 删除 Delete ****************************/
//删除索引为index的元素
public void remove(int index){
if(index<0||index>=size){
System.err.println("remove index illegal!");
return ;
}
for(int i=index;i<size-1;i++){
//防止当size==data.length时,data[i+1]会越界
data[i] = data[i+1];
}
size--;
data[size] = 0;
//将最后一个没有被覆盖的元素赋为0
}
//删除第一个num元素
public void removeOnceNum(int num){
if(indexOf(num) == -1){
System.err.println("remove num illegal!");
return ;
}else{
for(int i=0;i<size;i++){
if(data[i] == num){
remove(i);
return ;
}
}
}
}
//删除所有的num元素
public void removeAllNum(int num){
if(indexOf(num) == -1){
System.err.println("remove num illegal!");
return ;
}else{
for(int i=0;i<size;i++){
while(i!=size && data[i]==num){
//确保索引i的位置完全删掉num
remove(i);
}
}
}
}
//重写Object类中的toString()方法,打印数组
@Override
public String toString(){
String str = "[";
for(int i=0;i<size;i++){
str += data[i];
if(i<size-1)
str += ", ";
}
str += "]";
return str;
}
//返回元素的个数
public int size(){
return this.size;
}
//扩容
private void grow(){
int[] data2 = Arrays.copyOf(this.data,this.data.length<<1);
this.data = data2;
}
}
思考
1.根据索引查找、修改元素的时间复杂度为O(1),较低
2.顺序表的插入删除,时间复杂度为O(N)
3.扩容需要申请新空间,拷贝数据,释放旧空间。会有很大的消耗。
4.扩容是呈1.5倍的增长,势必会有一定的空间浪费。
总结:
提示:这里对文章进行总结:
以上就是今天的学习内容,本文介绍了Java数据结构的顺序表的实现原理,学懂了这个自然也会掌握ArrayList的用法。之后的学习内容将持续更新!!!