陣列與鍊錶

2021-09-29 20:01:35 字數 3292 閱讀 6350

陣列和鍊錶是兩種資料結構,陣列非常簡單易用但是它有兩個非常大的缺點,乙個是陣列一旦建立無法擴充套件,另乙個則是陣列的查詢和刪除的速度很慢.

鍊錶改善了一些陣列的缺點,但是同樣的鍊錶自身也存在一些自己的缺點.

本篇部落格將為大家介紹一下這陣列和鍊錶特點及各自的優缺點.

大o表示法,一種粗略的評價計算機演算法效率的方法.後面的內容會用到表示效率的方法.

我們按陣列中的陣列是否排序對陣列進行劃分,將陣列分為無序陣列和有序陣列.無序陣列中的陣列是無序的,而有序陣列中的資料則是公升序或者降序排序的.

因為無序陣列中的資料是無序的,往陣列中新增資料時不用進行比較和移動資料,所以往無序陣列裡面新增資料很快.無論是新增第乙個資料還是第一萬個資料所需的時間是相同的,效率為o(1).

至於查詢和刪除速度就沒有那麼快了,以陣列中有一萬個資料項為例,最少需要比較1次,最多則需要比較一萬次,平均下來需要比較5000次,即n/2次比較,n代表資料量,大o表示法中常數可以忽略,所以效率為o(n).

結論:插入很快,因為總是將資料插入到陣列的空餘位置.

查詢和刪除很慢,假設陣列的長度為n,那麼平均的查詢/刪除的比較次數為n/2,並且還需要移動資料.

無序陣列中存放的資料是無序的,有序陣列裡面存放的資料則是有序的(有可能是公升序有可能是降序).

因為有序陣列中的資料是按公升序/降序排列的,所以插入的時候需要進行排序並且移動資料項,所有有序陣列的插入速度比無序陣列慢. 效率為o(n).

刪除速度和無序陣列一樣慢 效率為o(n).

有序陣列的查詢速度要比無序陣列快,這是因為使用了乙個叫做二分查詢的演算法.

二分查詢: 二分查詢也稱折半查詢(binary search),它是一種效率較高的查詢方法。但是,折半查詢要求線性表必須採用順序儲存結構,而且表中元素按關鍵字有序排列.

有乙個關於二分查詢的形象模擬 -> 猜數遊戲

假設要在0-100之間猜乙個數,那麼你第乙個要猜的數字就是100的一半50的時候,你的朋友會告訴你這個數字比要猜的數字是大還是小,如果比數字大,你接下來要猜的數字就是50的一半25,你的朋友說比這個數字要大,那麼你下面要猜的數字就是25-50中間的那個數37,以此類推...

使用二分查詢可極大的提高查詢的效率,假設乙個有序陣列有十億個資料,那麼查詢到所需的數字,最多隻需比較30次.

有序陣列使用二分查詢的效率為o(logn).有序陣列也可以通過二分查詢來新增和刪除資料以提高效率,但是依然需要在新增/刪除後移動資料項,所以效率依然會有影響.

總結:有序陣列的查詢速度比無序陣列高,效率為o(logn)

有序陣列的刪除和新增速度很慢,效率為o(n)

陣列雖然簡單易用,但是陣列有兩個致命的缺點:

陣列儲存的數量有限,建立的過大浪費資源,建立的過小溢位

陣列的效率比其他資料結構低

陣列一經建立大小就固定住了,無法修改,鍊錶在這方面做出了改善,只要記憶體夠用就可以無限制的擴大.

鍊錶是繼陣列之後應用最廣泛的資料結構.

鍊錶為什麼叫鍊錶呢? 因為它儲存資料的方式就像一條鎖鏈

鍊錶儲存資料的方式很像上面的這一條鎖鏈,每一塊鎖鏈就是乙個鏈節點,鏈節點儲存著自己的資料同時通過自己的next()方法指向下乙個鏈節點. 鍊錶通過鏈節點不斷地呼叫next()方法就可以遍歷鍊錶中的所有資料.

在鍊錶中,每個資料項都被包含在"鏈節點"(link)中,乙個鏈結點是某個類的物件,這個類可以叫做link.因為乙個鍊錶中有許多類似的鏈結點,所以有必要用乙個不同於鍊錶的類來表達鏈結點.

每個link物件中都包含乙個對下乙個鏈結點引用的字段(通常叫做next).

鍊錶本身的物件中有乙個字段指向對第乙個鏈結點的引用.

資料與鍊錶查詢資料的區別: 在陣列中查詢資料就像在乙個大倉庫裡面一樣,一號房間沒有,我們去二號房間,二號房間沒有我們去三號房間,以此類推.. 按照位址找完所有房間就可以了.

而在鍊錶中查詢資料就像單線匯報的地下工作者,你是孤狼你想要匯報點情報給你的頂級上司毒蜂,但是你必須先報告給你的接頭人豬剛鬣,豬剛鬣在報告給它的單線接頭人土行孫,最後由土行孫報告給毒蜂.只能乙個找乙個,這樣最終完成任務.

鏈節點類:

/**

* @author liuboren

* @title: 鏈節點

* @description:

* @date 2019/11/20 19:30

*/public class link

public int getdata()

public void setdata(int data)

public link getnextlink()

public void setnextlink(link nextlink)

}

鍊錶類

/**

* @author liuboren

* @title: 鍊錶類

* @description:

* @date 2019/11/20 19:31

*/public class linklist

// 新增鏈節點方法

public void insertfirst(int data)

}

在新增節點的時候,新增的link的next方法指向原來的first節點,並將鍊錶類的first指向新增的節點.

剛剛介紹的鍊錶是單向鍊錶,只能從後往前遍歷,其他的鍊錶還有雙端鍊錶、雙向鍊錶、有序鍊錶.

再簡單介紹一下雙端鍊錶吧.

雙端鍊錶就是在單向鍊錶的基礎上,新增乙個成員變數指向鍊錶的最後乙個物件.

雙端鍊錶**:

/**

* @author liuboren

* @title: 鍊錶類

* @description:

* @date 2019/11/20 19:31

*/public class linklist

public boolean isempty()

// 新增鏈節點方法

public void insertfirst(int data)

first = newlink;}}

雙向鍊錶則是可以從first和last兩個方向進行遍歷,有序鍊錶的資料都是按照關鍵字的順序排列的,本文不再展開了.

鍊錶的效率:

鍊錶解決了陣列大小不能擴充套件的問題,但是鍊錶自身依然存在一些問題(在鍊錶的鏈節點後面查詢&刪除&插入的效率不高),那麼有沒有一種資料結構即擁有二者的優點又改善了二者的缺點呢,答案是肯定的,下篇部落格將為您介紹這種優秀的資料結構,敬請期待.

陣列與鍊錶

陣列和鍊錶簡介 在計算機中要對給定的資料集進行若干處理,首要任務是把資料集的一部分 當資料量非常大時,可能只能一部 分一部分地讀取資料到記憶體中來處理 或全部儲存到記憶體中,然後再對記憶體中的資料進行各種處理。例如,對於資料集 s,要求 s 中元素的和,首先要把資料儲存到記憶體中,然後再將記憶體中的...

陣列與鍊錶

陣列,在記憶體上給出了連續的空間.鍊錶,記憶體位址上可以是不連續的,每個鍊錶的節點包括原來的記憶體和下乙個節點的資訊 單向的乙個,雙向鍊錶的話,會有兩個 優點 使用方便 查詢效率 比煉表高,記憶體為一連續的區域 缺點 大小固定,不適合動態儲存,不方便動態新增 優點 可動態新增刪除 大小可變 缺點 只...

陣列與鍊錶

使用陣列意味著所有待辦事項在記憶體中都是相連的 緊靠在一起的 所以在陣列中新增新元素也可能很麻煩。如果沒有了空間,就得移到記憶體的其他地方,因此新增新元素的速度會很慢。一種解決之道是 預留座位 即便當前只有3個待辦事項,也請計算機提供10個位置,以防需要新增待辦事項。這樣,只要待辦事項不超過10個,...