鏈表通過指針將一組零散的內(nèi)存空間串聯(lián)起來使用。
單鏈表

鏈表.jpg
雙向鏈表

雙向鏈表.jpg
循環(huán)鏈表

循環(huán)鏈表.jpg
鏈表的特點
每一個內(nèi)存塊稱之為節(jié)點
為了將所有節(jié)點聯(lián)系起來 每個節(jié)點不僅要記錄數(shù)據(jù)還要記錄下一個內(nèi)存塊的地址
通常 第一個節(jié)點稱之為頭節(jié)點 最后一個節(jié)點稱之為尾結(jié)點
鏈表的相關(guān)操作
data:節(jié)點元素
next:后繼節(jié)點地址
下標(biāo)訪問:不支持
插入
q:插入的節(jié)點
p:當(dāng)前節(jié)點
只需p->next = q就可以了 時間復(fù)雜度為O(1)
刪除
k:刪除節(jié)點
單純的刪除操作只需將k節(jié)點刪除就可以了時間復(fù)雜度為O(1)
但刪除元素后要將指向k的指針也刪除 這就需要從頭遍歷了 時間復(fù)雜度為O(n)
這里有個小技巧 當(dāng)k不為尾結(jié)點時
k->data = k->next->data;
k->next = k->next->next;
然后刪除k->next 時間復(fù)雜度為 O(1)
查找
順序遍歷O(n)
將鏈表構(gòu)建為跳表 查找的時間復(fù)雜度為O(n)
LeetCode234 回文鏈表
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
public class Solution {
public boolean isPalindrome(ListNode head) {
ListNode fast = head, slow = head;
while (fast != null) {
if (fast.next == null) {
slow = slow.next;
break;
}
slow = slow.next;
fast = fast.next.next;
}
slow = reverse(slow);
fast = head;
while (slow != null) {
if (slow.val != fast.val) {
return false;
}
slow = slow.next;
fast = fast.next;
}
return true;
}
private ListNode reverse(ListNode head) {
if (head == null)
return null;
ListNode previous = null;
ListNode next = null;
while (head != null) {
next = head.next;
head.next = previous;
previous = head;
head = next;
}
return previous;
}
}