線性表,和鏈表。
線性表在內存中是一塊連續的存儲空間;如:一個表中的內容是:【1,2,3】則它在內存中可能是如下存儲的:
1
2
3
通過這個結構可以看出,只要知道了第一個元素在內存中所在的位置。就可以很容易的知道其他元素的位置。因為每一個元素占的空間是一樣的。所以,如果我們知道第一個元素:1在內存號:1000;而每一個元素占8個內存空間;則第二個元素:2所在的內存空間為:1000 + 8;依此類推。所以,
在線性表中訪問數據元素是很快的。它的缺點也正因為它是連續的一塊內存空間。所以,如果往中間添加或在中間刪除一個元素。都要移動其他的元素。如:我在最前面加入一個元素:0.則1,2,3都要往后移一位;或,我將1刪除,則2,3都要往前移一位;估算一下運算時間:在第一個元素處添加,要移動所有的元素。花費的時間是添加元素的時間 X 加上移動其他元素的時間:N,在最后面加元素不需要移動任何元素。時間僅為添加元素的時間: X .所以添加元素要的平均時間是 (N + 2X)/2;刪除操作和添加操作是一樣的;所以,
當改變線性表長度的時間,它會在移動元素上花費大量的時間。
在JAVA中。線性表的最直接應用就是數組:Array;但Array在初始化的時間必須規定其元素長度。如:
int[] arr = new int[5];必須規定其長度,但內容可以不填。它要知道長度,然后去開辟一塊內存空間。一旦數組初始化,它就不能往里面添加,刪除元素了。但可以將元素值設為空;
如果需要擴充數組長度,JAVA 提供了另一個類:ArrayList.
JAVA中所有的虛擬出來的數據容器都繼承自接口:Collection;ArrayList繼承自:List.而List又繼承了Collection;Collection提供了幾種基本方法:add();clear();remove();size();toArray();iterator()等;
ArrayList提供了較靈活的用法:
List<Long> lists = new ArrayList<Long>();
ArrayList<Long> lists = new ArrayList<Long>();
上面的用法使用了泛型。而且lists並未規定長度。它可以在程序中自由擴充。但這一特點就意味着它可能在運行時因為將內存耗盡而出現問題;數組是規定長度的,所以如果內存不足,你根本初始化不了,一旦初始化了就可以隨便用。
ArrayList,和Array都是數據結構中線性表的實現。
鏈表;
鏈表的存儲是鏈式的,它不強迫數據是在一片連續的內存空間;它可以是分散存儲的。所以,它的每個元素除了包括元素的值外,還要包括一些額外的信息;如:它的下一個元素在什么地方。
最基本的鏈式存儲中的元素包括兩部分:元素值和下個元素的位置;
可以如下理解:
內存空間: 值 下一元素空間
50 46 空
.
100 10 200
.
.
200 15 50
當存在這個鏈的時候,我們肯定知道鏈頭在哪,我們假設上面鏈頭在內存空間100處。則上述的鏈表表示的數據形式是:[10,16,46];知道了鏈頭在哪里,如果要查找其他元素。必須從鏈頭開始,依次查找下一內存空間里的值;所以查找用的時間為N/2;顯然就比線性表慢了。如果是刪除或添加元素。例,現在要將:[10,16,46]改成:[10,16,30,46];我們要做的是,將30放在內存中,假設它的內存地址是500;然后再將16這個值的下一元素空間的值改成500;並將30這一數值對應的下一元素空間值改成50(46這個值對應的內存空間);看起來要比線性表簡單。但細看會發現:要添加或刪除一個元素,必須知道它的上一個元素是誰;但現在數據中存儲的只有某一無線的下一個元素。如果要找上一個元素,則又要從鏈頭開始遍歷。這會浪費大量時間,還不如線性表好用。所以這時候出現了另一鏈表:
雙鏈表.它和基本鏈表不同的是,每個元素里不但存儲了下一個元素的空間,還存儲了上一個元素的空間。
JAVA 中對鏈表的實現是通過類:LinkedList 來實現的。LinkedList 最終也是上溯到了Collection接口;
所以它也有上面說的諸如:add().clear()等方法。