資料結構之陣列和鍊錶的區別

2021-10-03 14:42:38 字數 3754 閱讀 4664

陣列(array)

一、陣列特點:

所謂陣列,就是相同資料型別的元素按一定順序排列的集合;陣列的儲存區間是連續的,占用記憶體比較大,故空間複雜的很大。但陣列的二分查詢時間複雜度小,都是o(1);陣列的特點是:查詢簡單,增加和刪除困難;

1.1 在記憶體中,陣列是一塊連續的區域

1.2 陣列需要預留空間

在使用前需要提前申請所佔記憶體的大小,如果提前不知道需要的空間大小時,預先申請就可能會浪費記憶體空間,即陣列的空間利用率較低。注:陣列的空間在編譯階段就需要進行確定,所以需要提前給出陣列空間的大小(在執行階段是不允許改變的)
1.3 在陣列起始位置處,插入資料和刪除資料效率低。

插入資料時,待插入位置的元素和他後面的所有元素都需要向後搬移

刪除資料時,待刪除位置後面的所有元素都需要向前搬移。

1.4 隨機訪問效率很高,時間複雜度可以達到o(1)

因為陣列的記憶體是連續的,想要訪問那個元素,直接從陣列的首位址向後偏移就可以訪問到了。

1.5 陣列開闢的空間,在不夠使用的時候需要進行擴容;擴容的話,就涉及到需要把舊陣列中的所有元素向新陣列中搬移。

1.6 陣列的空間是從棧分配的。(棧:先進後出)

二、陣列的優點:

隨機訪問性強,查詢速度快,時間複雜度是0(1)

三、陣列的缺點:

3.1 從頭部刪除、從頭部插入的效率低,時間複雜度是o(n),因為需要相應的向前搬移和向後搬移。

3.2 空間利用率不高

3.3 記憶體空間要求高,必須要有足夠的連續的記憶體空間。

3.4 陣列的空間大小是固定的,不能進行動態擴充套件。

鍊錶(listnode)

一、鍊錶的特點:

所謂鍊錶,鍊錶是一種物理儲存單元上非連續、非順序的儲存結構,資料元素的邏輯順序是通過鍊錶中的指標鏈結次序實現的。鍊錶由一系列結點(鍊錶中每乙個元素稱為結點)組成,結點可以在執行時動態生成。每個結點包括兩個部分:乙個是儲存資料元素的資料域,另乙個是儲存下乙個結點位址的指標域。 相比於線性表順序結構,操作複雜。由於不必須按順序儲存,鍊錶在插入的時候可以達到o(1)的複雜度,比另一種線性表順序表快得多,但是查詢乙個節點或者訪問特定編號的節點則需要o(n)的時間,而線性表和順序表相應的時間複雜度分別是o(logn)和o(1)。

鍊錶:鍊錶儲存區間離散,占用記憶體比較寬鬆,故空間複雜度很小,但時間複雜度很大,達o(n)。鍊錶的特點是:查詢相對於陣列困難,增加和刪除容易。

1.1 在記憶體中,元素的空間可以在任意地方,空間是分散的,不需要連續。

1.3 查詢資料時間效率低,時間複雜度是o(n)

因為鍊錶的空間是分散的,所以不具有隨機訪問性,如果需要訪問某個位置的資料,需要從第乙個數開始找起,依次往後遍歷,知道找到待查詢的位置,故可能在查詢某個元素時,時間複雜度是o(n)
1.4 空間不需要提前指定大小,是動態申請的,根據需求動態的申請和刪除記憶體空間,擴充套件方便,故空間的利用率較高

1.5 任意位置插入元素和刪除元素時間效率較高,時間複雜度是o(1)

1.6 鍊錶的空間是從堆中分配的。(堆:先進先出,後進後出)

二、鍊錶的優點

2.1 任意位置插入元素和刪除元素的速度快,時間複雜度是o(1)

2.2 記憶體利用率高,不會浪費記憶體

2.3 鍊錶的空間大小不固定,可以動態拓展。

三、鍊錶的缺點

隨機訪問效率低,時間複雜度是o(1)

總之:對於想要快速訪問資料,不經常有插入和刪除元素的時候,選擇陣列

對於需要經常的插入和刪除元素,而對訪問元素時的效率沒有很高要求的話,選擇鍊錶

補充range()和arange()函式的區別:

range(start, end, step),返回乙個list物件也就是range.object,起始值為start,終止值為end,但不含終止值,步長為step。只能建立int型list。

arange(start, end, step),與range()類似,也不含終止值。但是返回乙個array物件。需要匯入numpy模組(import numpy as np或者from numpy import*),並且arange可以使用float型資料。

from numpy import*

arange(1,1.9,0.1) #可以是float型

array([ 1. , 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8])

range(1,10,2) #range(1,10,2)不會生成[1,3,5,6,9]而是生成乙個list物件

range(1, 10, 2)

for value in range(1,10,2)

syntaxerror: invalid syntax

for value in range(1,10,2):

print(value)

valuelist=list(range(1,10,1))

print(valuelist)

[1, 2, 3, 4, 5, 6, 7, 8, 9]

valuelist=list(range(1,10,0.1)) #range必須是int型

print(valuelist)

syntaxerror: multiple statements found while compiling a single statement

q1: 陣列和鍊錶取最大值的時間複雜度;

a1: 取最大值實際上就是對陣列和鍊錶分別進行訪問,則取最大值的時間複雜度分別是:陣列o(1),鍊錶o(n)

q2: 陣列和鍊錶的底層是用什麼寫的?

a2:陣列的底層是array list,鍊錶的底層是hashmap.

q3: hasmap衝突和溢位的解釋和處理方法:

a3:hash函式:

非雜湊表的特點:關鍵字在表中的位置和它之間不存在乙個確定的關係,查詢的過程為給定值一次和各個關鍵字進行比較,查詢的效率取決於和給定值進行比較的次數。

雜湊表的特點:關鍵字在表中位置和它之間存在一種確定的關係

雜湊函式:一般情況下,需要在關鍵字與它在表中的儲存位置建立乙個函式關係,以f(key)作為關鍵字為key的記錄在表中的位置,通常稱這個函式f(key)為雜湊函式。

hash:(雜湊)就是把任意長度的輸入,通過雜湊演算法,變成固定程度的輸出,該輸出就是雜湊值。這種轉換是一種壓縮對映,雜湊值的空間通常遠小於輸入的空間,不同的輸入可能會雜湊成相同的輸出,所以不可能從雜湊值來唯一的確定輸入值。 簡單的說就是一種將任意長度的訊息壓縮到莫伊固定長度的訊息摘要的函式。

hash衝突:就是根據key即經過乙個函式f(key)得到的結果的作為位址去存放當前的key value鍵值對(這個是hashmap的存值方式),但是卻發現算出來的位址上已經有人先來了。就是說這個地方被搶了啦。這就是所謂的hash衝突啦。

雜湊函式處理衝突的方法:

這種方法的基本思想是將所有雜湊位址為i的元素構成乙個稱為同義詞鏈的單鏈表,並將單鏈表的頭指標存在雜湊表的第i個單元中,因而查詢、插入和刪除主要在同義詞鏈中進行。鏈位址法適用於經常進行插入和刪除的情況。

3.再雜湊:

4.建立公共溢位區:

這種方法的基本思想是:將雜湊表分為基本表和溢位錶兩部分,凡是和基本表發生衝突的元素,一律填入溢位表

hashmap的hash衝突處理辦法

資料結構 陣列和鍊錶的區別

陣列和鍊錶是兩種基本的資料結構,他們在記憶體儲存上的表現不一樣,所以也有各自的特點 1.在記憶體中,陣列是一塊連續的區域 2.陣列需要預留空間 在使用前需要提前申請所佔記憶體的大小,這樣不知道需要多大的空間,就預先申請可能會浪費記憶體空間,即陣列空間利用率低 ps 陣列的空間在編譯階段就需要進行確定...

資料結構基礎之陣列和鍊錶

陣列 陣列 array 是有限個相同型別的變數所組成的有序集合。陣列中每個變數被稱為元素。陣列是最簡單 最常用的資料結構。陣列的另乙個特點,在記憶體中順序儲存。陣列中每乙個元素,都儲存在小小的記憶體單元中,並且元素之間緊密排列,既不能打亂元素的儲存順序,也不能跳過某個儲存單元進行儲存。陣列操作 增 ...

23 資料結構之陣列和鍊錶

特點 查詢和修改快 增加和刪除慢 arraylist和vector的底層是使用陣列的資料結構 在arraylist中初始化的長度是10,如果長度不夠用了,每次會增加之前長度的50 然後將舊的集合中的資料拷貝到新的集合中。vector每次擴容的長度是之前的一倍 陣列結構圖 為什麼查詢和修改快?查詢和修...