目录
一、线性表
线性表是n个具有相同特性的数据元素的有限数列。常见的线性表:顺序表、链表、栈、队列...
线性表在逻辑上是线性结构,也就是一条连续的直线,但是在物理结构上不一定连续,线性表在物理上存储时,通常以数组和链式结构的形式存储。
二、顺序表
顺序表是一种逻辑上连续,物理地址也连续的存储元素的线性结构,一般情况下采用数组存储,在数组上完成数据的增删查改。
三、ArrayList
3.1 ArrayList简介
在集合框架中,ArrayList是一个普通的类,它实现了List接口,具体如下:
1、ArrayList实现了RandomAccess接口,表明ArrayList支持随机访问;
2、ArrayList实现了Cloneable接口,表明ArrayList是可以clone的;
3、ArrayList实现了Serializable接口,表明ArrayList是支持序列化的;
4、和Vector不同,ArrayList不是线程安全的,在单线程下可以使用,在多线程中可以选择Vector或者CopyOnWriteArrayList;
5、ArrayList底层是一段连续的空间,并且可以动态扩容, 是一个动态类型的顺序表。
3.2 ArrayList的使用
3.2.1 ArrayList的构造方法
代码运行结果:
3.2.2 ArrayList中常用方法及实现
ArrayList中虽然提供了很多方法,但是常用的方法如下:
部分方法的实现:
class MyArrayList{
public int[] elem;
private int usedSize;
private static final int DEFAULT_CAPACITY = 10;
public MyArrayList(){
elem = new int[DEFAULT_CAPACITY];
}
// 打印顺序表
public void display() {
for (int i = 0; i < usedSize; i++) {
System.out.print(elem[i]+" ");
}
System.out.println();
}
private boolean isFull(){
return elem.length == usedSize;
}
// 新增元素,默认在数组最后新增
public void add(int data) {
if(isFull()){
elem = Arrays.copyOf(elem,elem.length*2);
}
elem[usedSize] = data;
usedSize++;
}
private void checkAddPos(int pos){
if(pos < 0 || pos > usedSize){
throw new PosNotLegalException("pos位置不合法");
}
}
// 在 pos 位置新增元素
public void add(int pos, int data) {
try {
checkAddPos(pos);
if(isFull()){
elem = Arrays.copyOf(elem,elem.length*2);
}
for (int i = usedSize-1; i >= pos; i--) {
elem[i+1] = elem[i];
}
elem[pos] = data;
usedSize++;
}catch (PosNotLegalException e){
e.printStackTrace();
}
}
// 判定是否包含某个元素
public boolean contains(int toFind) {
for (int i = 0; i < usedSize; i++) {
if(elem[i] == toFind){
return true;
}
}
return false;
}
// 从前往后查找某个元素对应的位置
public int indexOf(int toFind) {
for (int i = 0; i < usedSize; i++) {
if(elem[i] == toFind){
return i;
}
}
return -1;
}
//从后往前查找某个元素对应的位置
public int lastIndexOf(int toFind){
for (int i = usedSize - 1; i >= 0; i--) {
if(elem[i] == toFind){
return i;
}
}
return -1;
}
private void checkGetPos(int pos){
if(pos < 0 || pos >= usedSize){
throw new PosNotLegalException("pos位置不合法");
}
}
// 获取 pos 位置的元素
public int get(int pos) {
//检查pos合法性
checkGetPos(pos);
return elem[pos];
}
// 给 pos 位置的元素设为 value
public void set(int pos, int value) {
checkGetPos(pos);
elem[pos] = value;
}
//删除第一次出现的关键字key
public void remove(int key) {
int index = indexOf(key);
if(index == -1){
System.out.println("没有关键字"+key);
return;
}
for (int i = index; i < usedSize; i++) {
elem[i] = elem[i+1];
}
//引用数据类型要把elem[i]置为null
usedSize--;
}
// 获取顺序表长度
public int size() {
return usedSize;
}
// 清空顺序表
public void clear() {
/*for (int i = 0; i < usedSize; i++) {
elem[i] = null ;
}
引用数据类型要把elem[i]置为null*/
usedSize = 0;
}
}
3.3 ArrayList的遍历
ArrayList可以使用三种方式遍历:for循环、for-each、迭代器。
代码运行结果:
3.4 ArrayList的使用实例——杨辉三角
public class Test {
public static List<List<Integer>> generate(int numRows) {
List<List<Integer>> list = new ArrayList();
List<Integer> firstRow = new ArrayList();
firstRow.add(1);
list.add(firstRow);
for(int i = 1; i < numRows; i++){
List<Integer> row = new ArrayList();
row.add(1);
List<Integer> prevRow = list.get(i-1);
for(int j = 1; j < i ;j++){
int num = prevRow.get(j-1) + prevRow.get(j);
row.add(num);
}
row.add(1);
list.add(row);
}
return list;
}
public static void main(String[] args) {
List<List<Integer>> ret = generate(10);
for (int i = 0; i < ret.size(); i++) {
System.out.println(ret.get(i));
}
}
}
代码运行结果: