你們經過前幾章的學習,明白了什麼是單鏈表,相比於順序存儲,在插入和刪除方面,它的性能更加優越,可是小夥子們,有沒有想過在C語言和Java出現以前,只有Basic等早期語言,而這些語言沒有相似指針和地址的概念,那我們編程界的六道仙人是如何來描述鏈表的尼?java
對於沒有指針的編程語言,能夠用數組替代指針,來描述鏈表。讓數組的每一個元素由data和cur兩部分組成,其中cur至關於鏈表的next指針,這種用數組描述的鏈表叫作靜態鏈表。這種描述方法叫作遊標實現法 ,存儲方式以下圖所示git
固然,還有幾點規則github
(注:如上圖下標0或者下標999,這兩個位置數據爲空)編程
(注:如該數組第一個沒有存放數據的元素的下標是5,因此第一個元素的遊標是第一個沒有存放數據元素的下標,也就是說,下標0元素的遊標也是5)數組
(注:第一個存儲元素的下標爲1,那麼最後一個元素的遊標就是1)編程語言
也就是這樣性能
/** * 靜態鏈表中的對象 * */
public class Node<T> {
// 數據
T data;
// 遊標
int cur;
}
/** * 靜態鏈表 * */
public class StaticLinkedList<T> {
// 封裝的數組
private Node<T>[] arr;
/** * 初始化 * */
public StaticLinkedList(int length){
arr = new Node[length];
for(int i = 0; i < arr.length ;i++){
arr[i] = new Node<>();
// 非特殊點的元素遊標爲下一個元素的下標,
// 第一個元素遊標爲除特殊點外,第一個沒有數據的元素下標,如今鏈表爲空,因此第一個元素的遊標爲1
arr[i].cur = i + 1;
}
// 最後一個元素的遊標爲第一個存儲數據元素的下標,可是如今鏈表爲空,因此它的遊標爲0
arr[arr.length - 1].cur = 0;
}
}
複製代碼
完事以後就是這個熊樣學習
插入以前,先獲取空位下標,也就是說,要將數據插到哪spa
/** * 獲取空閒結點的下標 * */
public int getEmptyNodeIndex(){
// 獲取第一個元素的遊標,也就是一個數組中,第一個空閒元素的下標。默認爲0
int i = arr[0].cur;
if(i != 0){
// 第一個元素的遊標指向的是數組中第一個數據無值的元素下標,由於要將空閒位置插入元素,
// 因此將第一個元素(下標爲0)的遊標指向要插入值的元素以後的空閒元素下標
arr[0].cur = arr[i].cur;
}
return i;
}
複製代碼
注:如上圖所示,0號位置指向的是第一個空值的下標,也就是1號元素,因此先把1號元素取出,看看是否是最後一個元素,最後一個元素的遊標爲0,不是最後一個元素,就將它取出返回,由於要將數據插到這,因此0號元素的遊標指向了2號元素,由於如今2號元素的是空值。.net
好,獲取完空位座標以後,就開始插入元素了
(代碼)
/** * 插入數據 * */
public void addDataByIndex(int index, T value){
// 判斷插入的位置是否有效
if(index < 0 || index > arr.length){
throw new IllegalArgumentException("位置無效");
}
// 第一步:獲取可插入的位置下標
int emptyNodeIndex = getEmptyNodeIndex();
// 將數據插入
arr[emptyNodeIndex].data = value;
// 更新最後一個元素的遊標,它指向的是第一個有數據元素的下標
int k = arr.length - 1;
// 第二步:根據要插入的是第幾個位置,安裝個數,從最後一個元素的遊標開始往前推導,找出該元素所在遊標
for(int i = 1; i <= index - 1; i++){
k = arr[k].cur;
}
// 更新剛插入數據的元素的遊標爲,他上一個元素的遊標,也就是0,由於是從最後一個元素開始推的
arr[emptyNodeIndex].cur = arr[k].cur;
// 更新它上一個元素的遊標爲當前元素下標
arr[k].cur = emptyNodeIndex;
}
複製代碼
也就是這樣
同窗們,學會了嗎