1、数组
1.1 使用java中的数组
public class Test{
public static void main(String[] args){
int[] arr = new int[10];
for(int i=0 ; i<arr.length ; i++){
arr[i] = i;
}
int[] scores = new int[]{100,99,88};
for(int i=0; i<scores.length; i++){
System.out.println(scores[i]);
}
scores[0]=98;
for(int i=0; i<scores.length; i++){
System.out.println(scores[i]);
}
}
}
1.2 二次封装属于我们自己的数组
- 数组最大的有点就是:快速索引
- 但并非所有索引的地方均适用于数组
1.3 向数组中添加元素
1.4 数组中查询元素和修改元素
public class Array {
private int[] data;
private int size;
//构建一个指定大小的int数组
public Array(int capacity) {
data = new int[capacity];//进行强制转换
size = 0;
}
//构建一个大小为10的int数组
public Array() {
this(10);
}
//得到数据实际存储的元素数量
public int getSize() {
return size;
}
//得到数组的容量
public int getCapacity() {
return data.length;
}
//判断数组是否为空
public boolean isEmpty() {
return size == 0;
}
//向所有元素后面添加元素
public void addLast(int e) {
if(size == data.length)
throw new IllegalArgumentException("AddLast failed. Array is full");
data[size] = e;
size++;
}
//向所有元素前面添加元素
public void addFirst(int e) {
add(0,e);
}
//在数组的指定位置添加元素
public void add(int index,int e) {
if(index == data.length)
throw new IllegalArgumentException("Add failed. Array is full");
if(index <0 || index >size)
throw new IllegalArgumentException("Add failed. Require index >=0 && index <= size");
for(int i = size-1;i >= index; i--) {
data[i+1] = data[i];
}
data[index] = e;
size++;
}
@Override
public String toString() {
StringBuilder res = new StringBuilder();
res.append(String.format("Array: size = %d, capacity = %d\n",size,data.length));
res.append('[');
for(int i=0; i<size; i++){
res.append(data[i]);
if(i!=size-1)
res.append(", ");
}
res.append(']');
return res.toString();
}
//获取索引为index的元素
public int get(int index){
if(index<0 || index>=size)
throw new IllegalArgumentException("Get failed. index is illegal");
return data[index];
}
//设置索引所index的元素值
public void set(int index, int e){
if(index<0 || index>=size)
throw new IllegalArgumentException("Get failed. index is illegal");
data[index] = e;
}
//查看数组中是否包含元素e
public boolean contains(int e) {
for(int i=0; i<size; i++) {
if(data[i] == e) {
return true;
}
}
return false;
}
//从数组中寻找元素的位置
public int find(int e) {
for(int i=0; i<size; i++) {
if(data[i] == e) {
return i;
}
}
return -1;
}
//从数组中删除index位置的元素,返回删除的元素
public int remove(int index) {
if(index<0 || index>=size) {
throw new IllegalArgumentException("Remove failed. Index is illegal");
}
int ret = data[index];
for(int i= index+1; i<size; i++) {
data[i-1] = data[i];
}
size--;
return ret;
}
//从数组中删除第一个元素,并返回第一个元素
public int removeFirst() {
return remove(0);
}
//从数组中删除最后一个元素,并返回最后一个元素
public int removeLast() {
return remove(size-1);
}
//从数组中删除元素e
public void removeElement(int e) {
int index = find(e);
if(index!=-1) {
remove(index);
}
}
public static void main(String[] args) {
Array arr = new Array(10);
for(int i=0; i<10; i++){
arr.addLast(i);
}
//System.out.println(arr);
System.out.println(arr.toString());
arr.remove(2);
System.out.println(arr.toString());
}
}
1.5 使用泛型
让数据结构可以放置任何数据类型,但是不可以是基本数据类型,只能是类对象。虽然不能放置基本数据类型的数据,但是java 中为了解决该问题,为每种数据类型设置了对应的包装类,这样就可以放置这些包装类的对象。
boolean—>Boolean
byte—>Byte
等等
public class Array<E> {
private E[] data;
private int size;
//构建一个指定大小的int数组
public Array(int capacity) {
data = (E[])new Object[capacity];//进行强制转换
size = 0;
}
//构建一个大小为10的int数组
public Array() {
this(10);
}
//得到数据实际存储的元素数量
public int getSize() {
return size;
}
//得到数组的容量
public int getCapacity() {
return data.length;
}
//判断数组是否为空
public boolean isEmpty() {
return size == 0;
}
//向所有元素后面添加元素
public void addLast(E e) {
if(size == data.length)
throw new IllegalArgumentException("AddLast failed. Array is full");
data[size] = e;
size++;
}
//向所有元素前面添加元素
public void addFirst(int e) {
add(0,e);
}
//在数组的指定位置添加元素
public void add(int index,E e) {
if(index == data.length)
throw new IllegalArgumentException("Add failed. Array is full");
if(index <0 || index >size)
throw new IllegalArgumentException("Add failed. Require index >=0 && index <= size");
for(int i = size-1;i >= index; i--) {
data[i+1] = data[i];
}
data[index] = e;
size++;
}
@Override
public String toString() {
StringBuilder res = new StringBuilder();
res.append(String.format("Array: size = %d, capacity = %d\n",size,data.length));
res.append('[');
for(int i=0; i<size; i++){
res.append(data[i]);
if(i!=size-1)
res.append(", ");
}
res.append(']');
return res.toString();
}
//获取索引为index的元素
public E get(int index){
if(index<0 || index>=size)
throw new IllegalArgumentException("Get failed. index is illegal");
return data[index];
}
//设置索引所index的元素值
public void set(int index, E e){
if(index<0 || index>=size)
throw new IllegalArgumentException("Get failed. index is illegal");
data[index] = e;
}
//查看数组中是否包含元素e
public boolean contains(E e) {
for(int i=0; i<size; i++) {
if(data[i].equals(e)) {
return true;
}
}
return false;
}
//从数组中寻找元素的位置
public int find(E e) {
for(int i=0; i<size; i++) {
if(data[i].equals(e)) {
return i;
}
}
return -1;
}
//从数组中删除index位置的元素,返回删除的元素
public E remove(int index) {
if(index<0 || index>=size) {
throw new IllegalArgumentException("Remove failed. Index is illegal");
}
E ret = data[index];
for(int i= index+1; i<size; i++) {
data[i-1] = data[i];
}
size--;
return ret;
}
//从数组中删除第一个元素,并返回第一个元素
public E removeFirst() {
return remove(0);
}
//从数组中删除最后一个元素,并返回最后一个元素
public E removeLast() {
return remove(size-1);
}
//从数组中删除元素e
public void removeElement(E e) {
int index = find(e);
if(index!=-1) {
remove(index);
}
}
public static void main(String[] args) {
Array<Integer> arr = new Array<Integer>(10);//后面的Integer不是必须的
for(int i=0; i<10; i++){
arr.addLast(i);
}
//System.out.println(arr);
System.out.println(arr.toString());
arr.remove(2);
System.out.println(arr.toString());
}
}
public class Student {
String name;
int score;
public Student(String name ,int score) {
this.name = name;
this.score = score;
}
public String toString() {
return String.format("Student(name: %s, score: %d)",name score);
}
public static void main(String[] args) {
Array<Student> arr = new Array<>();
arr.addLast(new Student("lili",100));
arr.addLast(new Student("licy",90));
arr.addLast(new Student("dany",80));
System.out.println(arr);
}
}
//输出结果
Student(name: lili, score: 100)
Student(name: licy, score: 90)
Student(name: dany, score: 80)
1.6 动态数组
private void resize(int newCapacity) {
E[] newData = (E[]) new Object[newCapacity];
for(int i = 0; i < size ; i++) {
newData[i] = data[i];
}
data = newData;
}
1.7 简单的时间复杂度分析
大O分析法,实际时间T=C1*n+C2,忽略常数,得到时间复杂度为O(n),渐进时间复杂度,描述的其实是当n趋向于无穷大的时候。
T = 2nn+300n+100,这种情况下,时间复杂度依然是O(nn),因为当n趋向于无穷大的时候,n的平方大于n。
在时间复杂度分析下,一般以最坏的时间复杂度为标准。
- 添加操作
- addLast,O(1)
- addFirst,O(n)
- add(index,e) ,O(n/2)=O(n)
- resize,O(n)
- 删除操作
- removeLast,O(1)
- removeFirst,O(n)
- remove(index,e) ,O(n/2)=O(n)
- 查找操作
- get(index),O(1)
- set(index),O(1)
- 增:O(n),删:O(n),改/查:已知索引O(1),未知索引O(n)
- 均摊复杂度和放置复杂度的震荡
- 不是每次都会触发最坏的时间复杂度,讲最坏的时间复杂度平均分配到其他复杂度上