一.线性表
线性表是n个相同特征元素的有限序列。线性表在逻辑上是连续的,但在物理上不一定是连续的。线性表包括数组和链表。
顺序表结构:
链表结构:
二.顺序表
自己实现一个简单的顺序表:
public class MyArrayList {
public int[] elem;
//当前数组存储的有效数据个数
public int usedSize;
public static final int DEFAULT_SIZE=10;
public MyArrayList(){
this.elem=new int[DEFAULT_SIZE];
}
//获取顺序表的长度
public int size(){
return this.usedSize;
}
//判断是否包含某个元素
public boolean contains(int toFind){
for(int i=0;i<usedSize;i++){
if(toFind==this.elem[i]){
return true;
}
/* //如果是引用类型使用equals方法判等
if(toFind.equals(this.elem[i])){
return true;
}*/
}
return false;
}
//查找某个元素对应的位置
public int indexOf(int toFind) {
for (int i = 0; i < usedSize; i++) {
if (toFind == this.elem[i]) {
return i;
}
}
//数组下标没有负数
return -1;
}
//新增元素,默认放在数组的最后,O(1)
public void add(int data){
if(this.isFull()){
resize();
}
this.elem[this.usedSize]=data;
this.usedSize++;
}
//获取pos位置的元素
public int get(int pos){
checkGetIndex(pos);
return this.elem[pos];
}
//在pos位置新增元素,O(n)
public void add(int pos,int data){
checkAddIndex(pos);
if(isFull()){
resize();
}
for(int i=usedSize;i>=pos;i--){
elem[i]=elem[i-1];
}
elem[pos]=data;
this.usedSize++;
}
//给pos位置的元素更新位val,O(1)
public void set(int pos,int value){
checkGetIndex(pos);
this.elem[pos]=value;
}
//删除第一次出选的关键子key,O(n)
public boolean remove(int toRemove){
int index=indexOf(toRemove);
if(index==-1){
System.out.println("没有这个元素");
return false;
}
for(int i=index+1;i<=usedSize-1;i++){
elem[i-1]=elem[i];
}
usedSize--;
//如果时引用类型,要手动置空
elem[usedSize]=0;
return true;
}
//扩容
private void resize(){
this.elem= Arrays.copyOf(this.elem,2*this.elem.length);
}
//判断顺序表是否满
public boolean isFull(){
return this.elem.length==this.usedSize;
}
//插入数据时判断pos是否合法
private void checkAddIndex(int pos){
if(pos<0||pos>usedSize){
throw new AddIndexOutOfException("add时pos位置不合法");
}
}
//判断获取元素时pos位置是否合法
private void checkGetIndex(int pos){
if(pos<0||pos>=usedSize){
throw new AddIndexOutOfException("add时pos位置不合法");
}
}
//打印顺序表
public void display(){
for(int i=0;i<usedSize;i++){
System.out.print(this.elem[i]+" ");
}
}
//清空顺序表
public void clear(){
for(int i=0;i<usedSize;i++){
elem[i]=0;
}
usedSize=0;
}
}
顺序表插入和删除需要移动元素,时间复杂度位O(n),所以不适合频繁的对数据插入和删除,适合给定下标查找元素,时间复杂度为O(1)。
三.ArrayList使用
小练习:杨辉三角(力扣118)添加链接描述
解决思路:创建一个ArrayList,ArrayList里面还有一个ArrayList1,ArrayList2,…ArrayListn,ArrayListn,将ArrayListn添加进ArrayList里面,ArrayListn里面第一个和最后一个元素都是1,中间的元素是上一行上面的元素与上一行上面的元素前一个的和,示意图如下:
具体实现:
class Solution {
public List<List<Integer>> generate(int numRows) {
List<List<Integer>> ret=new ArrayList<>();
List<Integer> one=new ArrayList<>();
one.add(1);
ret.add(one);
for(int i=1;i<numRows;i++){
List<Integer> row=new ArrayList<>();
row.add(1);
List<Integer> list=ret.get(i-1);
for(int j=1;j<i;j++){
int sum=list.get(j)+list.get(j-1);
row.add(sum);
}
row.add(1);
ret.add(row);
}
return ret;
}
}
四.ArrayList的扩容机制
五.扑克牌的实现顺序表
ArrayList优点:当给定下标的时候,查找的速度非常快,适合给定下标查找。O(1)缺点:插入删除时须得挪动元素,每次扩容也浪费资源。