一、顺序表(ArrayList)
顺序表是用一段 物理地址连续 的存储单元依次存储数据元素的线性结构,一般情况下采用 数组 存储。
1. List
1.1 List的定义
List 是一个接口

2. 顺序表的结构
1.1 顺序表是一个类,实现了 List 接口

1.2 java系统中实现了顺序表的构造,如若需要使用提供的方法,可以直接调用系统的方法。
3. 自定义一个顺序表
java
public class SeqList {
private int[] data; // 构建一个数组,存储元素
public int size = 0; // 表示数组的有效长度
// 构造方法
public SeqList(){
data = new int[1024];
}
// 在尾部添加元素: 时间复杂度为 O(1)
public void add(int value){
//1. 判断数组容量是否够
if(size >= data.length){
realloc(); //对数组扩容
}
data[size] = value;
size++;
}
public void realloc(){
//1.创建一个新的变量
int[] newData = new int[data.length *2];
for (int i = 0; i < size; i++) {
newData[i] = data[i];
}
data = newData;
}
// 中间位置添加元素: 时间复杂度为 O(N)
public void add(int index, int value){
//1. 判断数组容量是否够
if(size >= data.length){
realloc();
}
//2. 把要添加的位置元素依次往后挪一格
for (int i = size-1; i >= index ; i--) {
data[i+1] = data[i];
}
//3. 直接在该位置上添加新元素
data[index] = value;
size++;
}
// 判断元素是否存在: 时间复杂度为 O(N)
public boolean contains(int value){
for (int i = 0; i < size; i++) {
if(data[i] == value){
return true;
}
}
return false;
}
// 找到元素在顺序表的位置: 时间复杂度为 O(N)
public int indexOf(int value){
for (int i = 0; i < size; i++) {
if(data[i] == value){
return i;
}
}
return -1;
}
// 按照位置删除元素: 时间复杂度为 O(N)
public void remove(int index){
//1. 判断 index 是否合法
if(index < 0 || index >= size){
throw new RuntimeException("索引越界");
}
//2. 将该位置之后的元素都往前挪一格
for (int i = index; i < size-1; i++) {
data[i] = data[i+1];
}
size--;
}
// 按照值删除元素:时间复杂度为 O(N)
public void removeByValue(int value){
//1.遍历数组,找到该值的下标位置
int index = indexOf(value);
//2. 如果不存在,直接返回
if(index == -1){
return;
}
//3. 调用上面的 根据位置删除元素 的方法
remove(index);
}
//get方法: 时间复杂度为 O(1)
public int get(int index){
if(index < 0 || index >= size){
throw new RuntimeException("索引越界");
}
return data[index];
}
// set 方法: 时间复杂度为 O(1)
public int set(int index, int value){
return data[index] = value;
}
4. ArrayList 的使用方式
(1) ArrayList是以泛型方式实现的,使用时必须先实例化
java
ArrayList<E> list = new ArrayList<>();
(2)ArrayList 实现了 Clonable 接口,表明 ArrayList 是可以 clone(浅拷贝) 的
java
import java.util.ArrayList;
class User{
String name;
public User (String name){
this.name = name;
}
}
public class Demo{
public static void main(String[] args) {
ArrayList<User> list1 = new ArrayList<>();
list1.add(new User("张三"));
list1.add(new User("李四"));
ArrayList<User> list2 = (ArrayList<User>) list1.clone();
System.out.println(list1 == list2); //false 原因是:ArrayList 的 clone 是浅拷贝
System.out.println(list1.get(0) == list2.get(0));//true 原因是: 元素引用时同一个
list1.get(0).name = "改名了";
System.out.println(list2.get(0).name); // 改名了
}
}
(3)ArrayList 底层是一段连续的空间,并且可以动态扩容,是一个动态类型的顺序表
5. ArrayList的应用场景
5.1 构造一副牌
java
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
class Card{
private String rank; //点数
private String suit; //花色
public String getRank() {
return rank;
}
public void setRank(String rank) {
this.rank = rank;
}
public String getSuit() {
return suit;
}
public void setSuit(String suit) {
this.suit = suit;
}
@Override
public String toString() {
return suit + rank;
}
}
public class CardDemo {
private static List<Card> buyCards(){
List<Card> cards = new ArrayList<>();
String[] suits = {"♠️", "♥️", "♣️", "♦️"};
for (int i = 0; i < suits.length; i++) {
for (int j = 2; j <= 10; j++) {
Card card = new Card();
card.setSuit(suits[i]);
card.setRank(j + "");
cards.add(card);
}
Card cardJ = new Card();
cardJ.setSuit(suits[i]);
cardJ.setRank("J");
Card cardQ = new Card();
cardQ.setSuit(suits[i]);
cardQ.setRank("Q");
Card cardK = new Card();
cardK.setSuit(suits[i]);
cardK.setRank("K");
Card cardA = new Card();
cardA.setSuit(suits[i]);
cardA.setRank("A");
cards.add(cardJ);
cards.add(cardQ);
cards.add(cardK);
cards.add(cardA);
}
return cards;
}
// 洗牌
private static void shuffle(List<Card> cards){
Random random = new Random();
for (int i = cards.size()-1; i > 0; i--) {
int r = random.nextInt(i);
Card temp = cards.get(r);
cards.set(r, cards.get(i));
cards.set(i,temp);
}
}
public static void main(String[] args) {
List<Card> cards = buyCards();
//System.out.println(cards);
shuffle(cards);
//System.out.println(cards);
// 发牌
List<Card> player1 = new ArrayList<>();
List<Card> player2 = new ArrayList<>();
List<Card> player3 = new ArrayList<>();
List<List<Card>> players = new ArrayList<>();
players.add(player1);
players.add(player2);
players.add(player3);
for (int i = 0; i < 5; i++) {
for (int j = 0; j < players.size(); j++) {
Card card = cards.remove(0);
players.get(j).add(card);
}
}
for (int i = 0; i < players.size(); i++) {
System.out.println("玩家" + (i + 1) + "" + ":" + players.get(i));
}
}
}
5.2 杨辉三角
java
import java.util.ArrayList;
import java.util.List;
public class yangHUi {
public List<List<Integer>> generate(int numRows) {
List<List<Integer>> ret = new ArrayList<>();
for (int rowIndex = 0; rowIndex < numRows; rowIndex++) {
List<Integer> row = new ArrayList<>();
for (int colIndex = 0; colIndex < rowIndex+1; colIndex++) {
if(colIndex == 0 || colIndex == rowIndex){
row.add(1);
}else {
List<Integer> prevRow = ret.get(rowIndex-1);
int value1 = prevRow.get(colIndex - 1);
int value2 = prevRow.get(colIndex);
row.add(value1 + value2);
}
}
ret.add(row);
}
return ret;
}
public static void main(String[] args) {
yangHUi y = new yangHUi();
List<List<Integer>> ret = y.generate(5);
System.out.println(ret);
}