寫在前面: 博主是一名軟件工程系大數據應用開發專業大二的學生,暱稱來源於《愛麗絲夢遊仙境》中的Alice和自己的暱稱。作爲一名互聯網小白,
寫博客一方面是爲了記錄自己的學習歷程,一方面是希望能夠幫助到很多和自己一樣處於起步階段的萌新
。由於水平有限,博客中難免會有一些錯誤,有紕漏之處懇請各位大佬不吝賜教!個人小站:http://alices.ibilibili.xyz/ , 博客主頁:https://alice.blog.csdn.net/
儘管當前水平可能不及各位大佬,但我還是希望自己能夠做得更好,因爲一天的生活就是一生的縮影
。我希望在最美的年華,做最好的自己
!
先來解釋下博主爲什麼會在這個時候開設一個專欄來學習【數據結構和算法】。
就像各位所知道的,在如今的互聯網招聘中,面試官越來越着重考察應聘者的一個基礎實力。像數據結構與算法,如果一點沒接觸,連門檻都進不去(尤其是大廠,不會算法基本沒戲)。而博主,作爲一個00後,大二的學生,很不幸地在過去一年多時間裏幾乎沒有接觸過數據結構和算法。雖然我並不抱着實習就能進大廠的打算,但是從長遠的角度出發,早點開始學習數據結構和算法,並非一件壞事。至少等到實力充足了,例如工作了兩三年,完全可以通過社招的形式憑本事進大廠。所以在閒暇之餘,就自己開設了一個專欄,用於沒事的時候寫寫,就當是爲自己補充能量了吧哈哈。
好了,不多嗶嗶了,在正式開始之前,先奉上一張大佬製作的思維導圖(來源:https://www.cnblogs.com/zhanghaodong/p/10281923.html)。可謂總結的非常精闢,而我作爲一個入門級選手,決定後面就按着這個路線去學習。
本篇我們先來學習數組。
基本概念
數組是由有限個相同類型的變量所組成的有序集合,它的物理存儲方式是順序存儲,訪問方式是隨機訪問。利用下標查找數組元素的時間複雜度是O(1),中間插入,刪除數組元素的時間複雜度是O(n)。
特點
- 在內存中,數組是一塊連續的區域
- 數組需要預留空間(數組的空間在編譯階段就需要進行確定,所以需要提前給出數組空間的大小),預先申請可能會浪費內存空間,即數組空間利用率低
- 在數組起始位置處,插入數據和刪除數據效率低。
- 隨機訪問效率很高,時間複雜度可以達到O(1)
- 數組開闢的空間,在不夠使用的時候需要擴容,擴容的話,就會涉及到需要把舊數組中的所有元素向新數組中搬移
- 數組的空間是從棧分配的
常用操作
插入數據
/**
* 數組插入元素
* @param index 插入的位置
* @param element 插入的元素
*/
public void insert(int index, int element) throws Exception {
//判斷訪問下標是否超出範圍
if(index<0 || index>size){
throw new IndexOutOfBoundsException("超出數組實際元素範圍!");
}
//如果實際元素達到數組容量上線,數組擴容
if(size >= array.length){
resize();
}
//從右向左循環,逐個元素向右挪一位。
for(int i=size-1; i>=index; i--){
array[i+1] = array[i];
}
//騰出的位置放入新元素
array[index] = element;
size++;
}
數組擴容
/**
* 數組擴容
*/
public void resize(){
int[] arrayNew = new int[array.length*2];
//從舊數組拷貝到新數組
System.arraycopy(array, 0, arrayNew, 0, array.length);
array = arrayNew;
}
刪除元素
/**
* 數組刪除元素
* @param index 刪除的位置
*/
public int delete(int index) throws Exception {
//判斷訪問下標是否超出範圍
if(index<0 || index>=size){
throw new IndexOutOfBoundsException("超出數組實際元素範圍!");
}
int deletedElement = array[index];
//從左向右循環,逐個元素向左挪一位。
for(int i=index; i<size-1; i++){
array[i] = array[i+1];
}
size--;
return deletedElement;
}
輸出數組
/**
* 輸出數組
*/
public void output(){
for(int i=0; i<size; i++){
System.out.println(array[i]);
}
}
完整代碼
public class MyArray {
private int[] array;
private int size;
public MyArray(int capacity){
this.array = new int[capacity];
size = 0;
}
/**
* 數組插入元素
* @param index 插入的位置
* @param element 插入的元素
*/
public void insert(int index, int element) throws Exception {
//判斷訪問下標是否超出範圍
if(index<0 || index>size){
throw new IndexOutOfBoundsException("超出數組實際元素範圍!");
}
//如果實際元素達到數組容量上線,數組擴容
if(size >= array.length){
resize();
}
//從右向左循環,逐個元素向右挪一位。
for(int i=size-1; i>=index; i--){
array[i+1] = array[i];
}
//騰出的位置放入新元素
array[index] = element;
size++;
}
/**
* 數組擴容
*/
public void resize(){
int[] arrayNew = new int[array.length*2];
//從舊數組拷貝到新數組
System.arraycopy(array, 0, arrayNew, 0, array.length);
array = arrayNew;
}
/**
* 數組刪除元素
* @param index 刪除的位置
*/
public int delete(int index) throws Exception {
//判斷訪問下標是否超出範圍
if(index<0 || index>=size){
throw new IndexOutOfBoundsException("超出數組實際元素範圍!");
}
int deletedElement = array[index];
//從左向右循環,逐個元素向左挪一位。
for(int i=index; i<size-1; i++){
array[i] = array[i+1];
}
size--;
return deletedElement;
}
/**
* 輸出數組
*/
public void output(){
for(int i=0; i<size; i++){
System.out.println(array[i]);
}
}
public static void main(String[] args) throws Exception {
MyArray myArray = new MyArray(4);
myArray.insert(0,3);
myArray.insert(1,7);
myArray.insert(2,9);
myArray.insert(3,5);
myArray.insert(1,6);
myArray.insert(5,8);
myArray.delete(3);
myArray.output();
}
}
本篇博客中代碼來源於《漫畫算法》,應本書作者要求,加上本書公衆號《程序員小灰》二維碼。
感興趣的朋友可以去購買正版實體書,確實不錯,非常適合小白入門。
總結
數組的優勢:
數組擁有非常高效的隨機訪問能力,只要給出下標,就可以用常量時間找到對應元素。有一種高效查找元素的算法叫作二分查找,就是利用了數組的這個優勢。
數組的劣勢:
數組的劣勢,體現在插入,刪除元素方面。由於數組元素連續緊密地存儲在內存中,插入、刪除元素都會導致大量元素被迫移動,影響效率。
總的來說,數組所適合的是讀操作多,寫操作少的場景,下一節 我們要講解的鏈表則恰恰相反。
如果以上過程中出現了任何的紕漏錯誤,煩請大佬們指正😅
受益的朋友或對大數據技術感興趣的夥伴記得點贊關注支持一波🙏
希望我們都能在學習的道路上越走越遠😉