基礎資料結構(一) 陣列
阿新 • • 發佈:2022-04-12
基礎資料結構(一):陣列
面試經典:
給你一個檔案裡面包含全國人民的年齡資料,現在要你統計每一個年齡有多少人?
給定機器為單臺+2CPU+2G記憶體。不得使用現成的容器,比如map等
在以上情況下你該如何以最高效的方法來解決這個問題?
解題思路
首先排序演算法能否使用呢?遍歷
從演算法時間複雜度分析 最快O(N) N=14億 想象一下能排的出來嗎?
並且記憶體不夠(6G塞不了2G)
這時候我們就能使用一種非常簡單的方法處理 【陣列演算法】
瞧
全國人民 14億
年齡 0~180
int data [] = new int[180];
這不就OK了嗎?
data[0]++; // 0 歲人加一 data[0] 的值就表示0歲有多少人
下面看程式碼 (最主要的就是讀取檔案時一行一行讀)
InputStreamReader isr = new InputStreamReader(new FileInputStream(fileName), "UTF-8"); BufferedReader br = new BufferedReader(isr); int tot = 0 ; //21億 int data [] = new int[200]; while((str = br.readLine()) != null){ //一行一行的讀 O(n) int age = Integer.parseInt(str); data[age] ++ ; tot ++ ; }
這裡突出的就是陣列的一個最優特點【下標】
陣列是什麼?
- 有序的元素序列
- 用於儲存多個同類型資料的集合 通常使用【Array】表示 也叫做線性表
陣列特點
- 陣列是相同資料型別的元素的集合。
- 陣列中的各元素的儲存是有先後順序的,它們在記憶體中按照這個先後順序連續存放在一起。記憶體地址
- 陣列元素用整個陣列的名字和它自己在陣列中的順序位置來表示。例如,a[0]表示名字為a的陣列中的第一個元素,a[1]代表陣列a的第二個元素,以此類推。
陣列表現形式
int[] a; // 一維陣列
int[][] b; // 多維陣列
隨機訪問
陣列是連續的記憶體空間和相同型別的資料
正是因為這兩個限制,它才有了一個非常重要的特性:【隨機訪問】
但有利就有弊,這兩個限制也讓陣列的很多操作變得非常低效,
比如要想在陣列中刪除、插入一個數據,為了保證連續性,就需要做大量的資料搬移工作。
隨機訪問的重要應用:查詢,面試重點
如何實現一個數組的增刪改查?
package model;
/**
* @author : ywb
* @date : 2022-04-12 14:01
*/
public class MyArray {
final int size; //陣列的長度
final int[] data;
private int index; //當前已經存的資料大小
public MyArray(int size) {
this.size = size;
data = new int[size]; //分配的記憶體空間{0,0,0,0,0}
index = 0;
}
public void print(){
System.out.println("index:" + index);
Arrays.stream(data).forEach(System.out::print);
System.out.println();
}
public void insert(int loc,int n){ //時間複雜度 O(n);
if(index ++ < size){
for(int i = size - 1; i > loc ; i --){ //為什麼不能寫size 0~size-1 如果loc是0 O(n),O(1)=>O(n)
data[i] = data[i - 1]; //把資料往後移一個
}
data[loc] = n;
}
//擴容 會把size*2 0.75
}
public void delete(int loc){ //O(n)
for(int i = loc ; i < size ; i++){
if(i != size - 1){ //怕越界所以加一個判斷
data[i] = data[i + 1];
}else{
data[i] = 0; //預設為0 就是沒存資料的
}
}
index -- ;
}
public void update(int loc,int n){ //O(1)
data[loc] = n;
}
public int get(int loc){ //O(1)
return data[loc];
}
}
實現總結
根據實現可以看出
插入 刪除 屬於複製新陣列 資料挪移 時間複雜度O(n)
查詢 修改 使用下標訪問 時間複雜度O(1)
所以 【增刪】慢 【查改】 快
下面來說下ArrayList吧?
ArrayList 和陣列
首先本質都是一樣的 陣列
但是ArrayList 是JDK封裝了。不需要管擴容等操作
陣列的話就要你全部操作
兩者之間應該如何選用?
不知道資料大小的肯定選ArrayList.
如果你知道資料的大小而且你又非常關注效能那就用陣列。
總結
陣列是一個最基礎最簡單的資料結構
它是儲存相同型別的一組資料,最大的兩個特點就是
【下標】和【隨機訪問】缺點就是插入和刪除是很慢的,時間複雜度為O(n)。