1、在分配空間上:
數組分配在一塊連續的數據空間上,因此在分配空間時必須確定大小,鏈表是一塊不連續的動態空間,通過指針練連接,因此長度可變;
2、數組
優點:
1、可以利用偏移地址來訪問元素,效率高,為O(1);
2、可以使用折半方法查找元素,效率較高;
缺點:
1、空間連續,存儲效率低
2、插入和刪除元素效率比較低,且比較麻煩;
3、鏈表
優點:
1、插入和刪除元素不需要移動其余元素,效率高,為O(1);
2、不要求連續空間,空間利用效率高
缺點:
1、不提高隨機訪問元素的限制
2、查找元素和搜索元素的效率低,最快情況為O(1),平均情況為O(N);
因此對於經常插入和刪除的操作,數據結構采用鏈表或者使用二叉搜索樹;
鏈表和數組都可用來存放指定的數據類型。
首先分別介紹一下鏈表和數組。
鏈表的特性是在中間任意位置添加刪除元素的都非常的快,不需要移動其它的元素。通常鏈表每一個元素都要保存一個指向下一個元素的指針(單鏈表)。雙鏈表的話每個元素即要保存到下一個元素的指針,還要保存一個上一個元素的指針。循環鏈表則把最后一個元素中保存下一個元素指針指向第一個元素。
數組是一組具有相同類型和名稱的變量的集合。這些變量稱為數組的元素,每個數組元素都有一個編號,這個編號叫做下標,我們可以通過下標來區別這些元素。數組元素的個數有時也稱之為數組的長度。
數組是將元素在內存中連續存放,由於每個元素占用內存相同,所以你可以通過下標迅速訪問數組中任何元素。但是如果你要在數組中增加一個元素,你需要移動大量元素,在內存中空出一個元素的空間,然后將要增加的元素放在其中。同樣的道理,如果你想刪除一個元素,你同樣需要移動大量元素去填掉被移動的元素。
鏈表恰好相反,鏈表中的元素在內存中不是順序存儲的,而是通過存在元素中的指針聯系到一起。比如:上一個元素有個指針指到下一個元素,以此類推,直到最后一個元素。如果你要訪問鏈表中一個元素,你需要從第一個元素開始,一直找到你需要的元素位置。但是增加和刪除一個元素對於鏈表數據結構就非常簡單了,只要修改元素中的指針就可以了。
從上面的比較你可以看出,如果你的應用需要快速訪問數據,很少或不插入和刪除元素,你就應該用數組;相反,如果你的應用需要經常插入和刪除元素你就需要用鏈表數據結構了。然后你自己可以想一想什么樣的應用用鏈表合適。
C++語言中可以用數組處理一組數據類型相同的數據,但不允許動態定義數組的大小,即在使用數組之前必須確定數組的大小。而在實際應用中,用戶使用數組之前有時無法准確確定數組的大小,只能將數組定義成足夠大小,這樣數組中有些空間可能不被使用,從而造成內存空間的浪費。
鏈表是一種常見的數據組織形式,它采用動態分配內存的形式實現。需要時可以用new分配內存空間,不需要時用delete將已分配的空間釋放,不會造成內存空間的浪費。
從邏輯結構來看
A-1. 數組必須事先定義固定的長度(元素個數),不能適應數據動態地增減的情況。當數據增加時,可能超出原先定義的元素個數,出現溢出現象;當數據減少時,造成內存浪費。數組中插入、刪除數據項時,需要移動其它數據項。
A-2. 鏈表動態地進行存儲分配,可以適應數據動態地增減的情況,且可以方便地插入、刪除數據項。
從內存存儲來看
B-1. (靜態)數組從棧中分配空間, 對於程序員方便快速,但是自由度小
B-2. 鏈表從堆中分配空間, 自由度大但是申請管理比較麻煩.
前面說的是單向鏈表和靜態數組,下面簡單介紹一下雙向鏈表和動態數組。
動態數組其實比較簡單,就是一個長度可以根據實際情況改變的數組。我們如果要查找某一個動態數組中的元素,可以通過get()方法來查找,只要知道該元素下標就可以了。
雙向鏈表存放的除了本來的數據外,還有其前驅和后驅結點。
在動態數組中,如果我們要在某一個位置添加或者刪除一個元素,剩下的每個元素都要相應地往前或往后移動。如果該動態數組中的元素很多,那么,每當我們添加或刪除一個元素后,需要移動的元素就非常多,因此,效率就比較低。
雙向鏈表效率就高多了。如果我們要在某一個位置添加一個元素,例如,要在1,3之間插入5。本來1是指向3,3也指向1的。現在,只需要將5放到1和3之間,同時讓5向前指向1,向后指向3,並且讓1從3指向5,讓3從1指向5就可以了。如果該鏈表中元素非常多,我們只需做這個操作就可以了,並不需要移動剩下的元素。
所以,雙向鏈表在添加和刪除元素上的效率要比動態數組高很多。java中系統同時提供了雙向鏈表(LinkedList)和動態數組(ArrayList)兩種機制。並且,Java中有一個叫ListIterator的迭代器。該迭代器不僅可以向后迭代元素,還能向前迭代,而且還有add()來在某一位置添加元素,十分方便。不過查找效率的話就反過來了,是動態數組的效率比雙向鏈表的效率高,因為你只要提供元素的下標即可。
注:鏈表由於存放的地方在內存中是分散的,因此cpu的基地址寄存器等等必須重新賦值,而數組這一過程是不要的。因此對於查詢來說,數組的效率更好。