php 插入陣列尾部 資料結構與演算法系列之陣列

2021-10-19 05:42:11 字數 3205 閱讀 6571

忘了在哪本書看見過一句話「理解了概念性的東西,你就學會了70%」

回到主題,什麼是陣列?

陣列(array)是一種線性表資料結構。它用一組連續的記憶體空間,來儲存一組具有相同型別的資料

概念中有兩個關鍵的地方:

陣列是一種線性資料結構

陣列中儲存的是連續的記憶體空間和相同型別的資料

什麼是線性資料結構

有資料結構基礎的小夥伴都應該知道,線性結構就是資料排成一條線一樣的資料結構,也就意味著它僅有前後兩個方向,比如佇列、單鏈表、棧等,也是線性結構

與它相對的就是非線性表,最典型的就是樹和圖。他們的特點就是並不是只有前後這種關係

連續的記憶體空間和相同型別的資料

正因為有了這個特性,使得陣列可以進行「隨機訪問」。雖然訪問陣列中某個元素變得很快,但缺點就是在修改(刪除、插入)陣列的時候,操作會變得很麻煩,因為要保證陣列記憶體空間的連續性,所以不得不進行繁瑣的資料移動

假設有乙個長度為5的int型別的陣列var a [5]int,假設給這個陣列分配的記憶體空間首位址是1000,則這個陣列分配的記憶體空間為1000~1019,看下圖

作業系統會為每乙個記憶體單眼分配乙個位址,通過這個位址來訪問記憶體中的資料。當作業系統需要隨機訪問陣列中的某乙個元素時,它會通過下邊這個定址公式來計算出某個元素的儲存位址

a[i]_address = base_address + i * data_type_size

data_type_size:表示陣列中每個元素的大小。比如int型別,它占用的是4個位元組,所以這裡data_type_size就是4

陣列和鍊錶的區別是什麼

通過上邊對陣列的介紹,可以看出來,陣列適合查詢操作。但是查詢的時間複雜度並不為o(1)。即便是排好序的陣列,你用二分查詢,時間複雜度也是o(logn)。所以,陣列支援隨機訪問,根據下標隨機訪問的時間複雜度為o(1)

插入元素

陣列頭部插入元素

在陣列的頭部插入元素,為了保證空間的連續性,需要將陣列中所有的元素向後移一位,然後將待插入元素放入到首部位置

**實現

function insertintohead($elem, $arr)

$arr[0] = $elem;

echo "頭部插入元素之後結果:".php_eol;

print_r($arr);

}

陣列中間插入元素在陣列的中間某個位置插入元素,需要將待插入位置以後的元素均向後移動一位

**實現

function insertintomid($elem, $position, $arr)

$arr[$head] = $value;

echo "頭部插入元素之後結果:".php_eol;

print_r($arr);

}

陣列尾部插入元素在尾部插入元素,不需要移動元素,直接放在當前的末尾元素後邊即可

刪除元素

陣列頭部刪除元素

刪除陣列頭部元素,將所有的元素向前移動一位即可

**實現:

function delhead($arr)

unset($arr[count($arr)-1]);echo "刪除後".php_eol;

print_r($arr);

}

陣列中間刪除元素將待刪除元素後邊的所有元素向前移動一位

**實現:

function delmid($position, $arr)

unset($arr[$len-1]);

echo "刪除後".php_eol;

print_r($arr);

}

陣列尾部刪除元素直接刪除即可,無需移動陣列中的元素

如果在陣列的末尾插入元素,那就不需要移動資料了,這時的時間複雜度為o(1)。但如果在陣列的開頭插入元素,那所有的資料都需要依次往後移動一位,所以最壞時間複雜度是o(n)。因為我們在每個位置插入元素的概率是一樣的,所以平均情況時間複雜度為(1+2+…n)/n=o(n)。刪除元素也是同理

從陣列儲存的記憶體模型上來看,「下標」最確切的定義應該是「偏移(offset)」。前面也說到,如果用a來表示陣列的首位址,a[0]就是偏移為0的位置,也就是首位址。a[k]就表示偏移k個 type_size 的位置,所以計算a[k]的記憶體位址只需要用這個公式

a[k]_address = base_address + k * type_size

但是,如果陣列從1開始計數,那我們計算陣列元素a[k]的記憶體位址就會變為

a[k]_address = base_address + (k-1)*type_size

對比兩個公式,我們不難發現,從1開始編號,每次隨機訪問陣列元素都多了一次減法運算,對於cpu來說,就是多了一次減法指令

陣列作為非常基礎的資料結構,通過下標隨機訪問陣列元素又是其非常基礎的程式設計操作,效率的優化就要盡可能做到極致。所以為了減少一次減法操作,陣列選擇了從0開始編號,而不是從1開始

參考:《資料結構與演算法之美》 《零基礎學資料結構》

往期文章

作業系統基礎(十五)---使用fork系統呼叫建立程序

程序同步之共享內

時間複雜度和空間複雜度

ip協議詳解

it猿圈

不做開始愛好者

php 陣列與資料結構

任意型別的資料,並且可以根據容器中儲存的資料決定容器的容量,打到可以變長的容器結構,比如鍊錶 堆疊和佇列等都是資料結構中常用的形式。在php中,通常都是使用陣列來完成其它語言使用資料結構才能完成的工作。它是若型別語言,在同乙個陣列中就可以儲存多種型別的資料,而且php中的陣列沒有長度限制,陣列儲存資...

算分與資料結構 冒泡思想

冒泡思想的乙個特點是所有的操作都在原陣列中進行,不占用額外的空間。一 氣泡排序 public class bubblesort public static void main string args new bubblesort bubblesort array for int i 0 i 二 冒泡...

Java資料結構與演算法之陣列排序 插入

a,對於隨機順序的資料進行插入排序需要o n2 的時間 b,當資料有序的時候,演算法執行需要o n 時間 c,當資料基本有序的時候,演算法幾乎只需要o n 時間 2 不變性 比outer變數下標號小的資料項都是區域性有序的。3 思路 a 設定乙個outer標籤,用於表示其左邊的元素已經排好,初始位置...