鏈表是一種物理存儲單元上非連續、非順序的存儲結構,數據元素的邏輯順序是經過鏈表中的指針鏈接次序實現的。面試
單向鏈表是一種線性表,其實是由節點(Node)組成的,每個鏈表都包含多個節點,節點又包含兩個部分,一個是數據域 data(儲存節點含有的信息),一個是引用域 next(儲存下一個節點或者上一個節點的地址)。其數據在內存中存儲是不連續的,它存儲的數據分散在內存中,每一個結點只能也只有它能知道下一個結點的存儲位置。由 N 個節點(Node)組成單向鏈表,每個 Node 記錄本Node的數據及下一個 Node。向外暴露的只有一個頭節點(Head),咱們對鏈表的全部操做,都是直接或者間接地經過其頭節點來進行的。算法
節點(Node)是由一個須要儲存的對象及對下一個節點的引用組成的。數組
1.節點Nodebash
public class LJLinkNode<T> {
public LJLinkNode next;
public T data;
public LJLinkNode() {
this.next = null;
this.data = null;
}
public LJLinkNode(T data) {
this.data = data;
this.next = null;
}
}
複製代碼
2.建立鏈表 在鏈表中有一個頭指針,它的next域用於指示鏈表第一個節點。ui
// 鏈表頭的引用 ,相似於頭指針
public LJLinkNode<T> headNode = new LJLinkNode<T>();
複製代碼
3.插入 在鏈表中插入一個節點,有尾插法,即在鏈表的尾部插入一個節點。首先須要判斷當前的鏈表是不是空鏈表,是的話就在頭節點進行插入,不是的話須要遍歷鏈表,到尾部進行插入節點:this
/**
* 插入一條數據
*
* @param value
*/
public void add(T value) {
// 若是是頭節點的話,在next指針域中插入
if (headNode.next == null) {
headNode.next = new LJLinkNode<>(value);
return;
}
LJLinkNode<T> tempNode = headNode;
while (tempNode.next != null) {
tempNode = tempNode.next;
}
tempNode.next = new LJLinkNode<>(value);
}
複製代碼
4.刪除一個節點spa
刪除一個指定位置上面的節點,首先須要遍歷到那個位置,而後將當前節點的前一個節點的next指向當前節點的後一個節點,即跳過當前節點。由於當前節點沒法獲取到它,所以就至關於刪除了。指針
/**
* 刪除指定index的一個節點
*
* @param data
*/
public boolean del(int index) {
// index下標越界
if (index < 0 || index > length()) {
return false;
}
// 刪除頭節點
if (index == 1) {
headNode = headNode.next;
return true;
}
LJLinkNode<T> preNode = headNode;
LJLinkNode<T> curNode = preNode.next;
int i = 2;
while (curNode != null) {
if (i == index) {
// 指向刪除節點的後一個節點
preNode.next = curNode.next;
break;
}
preNode = curNode;
curNode = preNode.next;
i++;
}
return true;
}
複製代碼
5.鏈表長度code
鏈表長度很好理解,遍歷鏈表便可:cdn
/**
* 鏈表長度
*
* @return
*/
public int length() {
int i = 0;
LJLinkNode<T> tempLinkNode = headNode;
while (tempLinkNode.next != null) {
i++;
tempLinkNode = tempLinkNode.next;
}
return i;
}
複製代碼
6.獲取指定位置上的鏈表節點
獲取到指定位置上的節點的話,須要遍歷到當前位置,而後獲取它的節點:
/**
* 獲取第index的節點
*
* @param index
* @return
*/
public LJLinkNode<T> getIndexLinkNode(int index) {
if (index < 0 || index > length()) {
return null;
}
LJLinkNode<T> tempNode = headNode;
int i = 0;
while (tempNode != null) {
if (index == i) {
break;
}
i++;
tempNode = tempNode.next;
}
return tempNode;
}
複製代碼
以上即是鏈表的基本操做,插入,刪除等。在面試過程當中還會有其餘的算法,咱們拿出幾個來簡單說明一下鏈表的算法應用。
1.合併兩個有序鏈表
將兩個有序鏈表合併爲一個新的有序鏈表並返回。新鏈表是經過拼接給定的兩個鏈表的全部節點組成的。
示例:
輸入:1->2->4, 1->3->4 輸出:1->1->2->3->4->4
來源:力扣(LeetCode) 連接:leetcode-cn.com/problems/me…