Linked List是一種基本的數據結構,它可以用來表示一組有序或無序的數據。從實現的角度,LinkedList可以是有序的也可以是無序的,這完全取決於我們在插入元素時所採取的策略。下面從多個方面闡述LinkedList有序還是無序。
一、插入元素的位置與有序性的關係
LinkedList有序或無序與插入元素的位置有很大關係。如果我們要將一個元素插入到LinkedList中的某個位置,比如第k個位置,那麼這個LinkedList必須是有序的。因為如果LinkedList是無序的,我們無法確定這個新元素應該插入到哪個位置,其它元素的位置也會發生變化,這將會帶來很大的麻煩。
而如果我們只是將新元素插入到LinkedList的尾部,或者只是將它插入到某個位置,但是不要求其它元素的位置改變,那麼LinkedList可以是有序的,也可以是無序的。這取決於我們是否有必要保持LinkedList的有序性。
// 插入元素到任意位置,需要保持LinkedList是有序的
public void insert(int val, int k) {
if (k size) throw new IllegalArgumentException("Illegal index.");
Node node = new Node(val);
if (k == 0) { // 插入到頭部
node.next = head;
head = node;
} else if (k == size) { // 插入到尾部
Node cur = head;
while (cur.next != null) cur = cur.next;
cur.next = node;
} else { // 插入到中間某個位置
Node prev = head;
for (int i = 0; i < k - 1; i++) prev = prev.next;
Node next = prev.next;
prev.next = node;
node.next = next;
}
}
二、搜索元素的效率與有序性的關係
在LinkedList中,搜索一個元素需要從頭到尾遍歷這個LinkedList,直到找到指定元素或者遍歷到尾部。如果LinkedList是有序的,我們可以通過二分查找來優化搜索效率,這樣可以將搜索時間降低到O(logn)。而如果LinkedList是無序的,則只能採用線性查找,搜索時間為O(n)。
// 二分查找的實現,需要保持LinkedList是有序的
public boolean search(int val) {
if (head == null) return false;
Node left = head, right = null;
// 找到LinkedList的尾部
while (left != null) {
right = left.next;
left = right != null ? right : null;
}
// 二分查找
left = head;
while (left != right) {
Node mid = left;
int cnt = 0;
// 計算左區間和右區間長度
while (mid != right && cnt = val) {
right = mid;
} else {
left = mid.next;
}
}
return left.val == val;
}
三、刪除元素的效率與有序性的關係
在LinkedList中,刪除一個元素需要找到它的前一個元素,將它的next指針指向下下個元素,再將要刪除的元素置為空,這樣才能釋放掉要刪除的元素。如果LinkedList是有序的,我們可以採用二分查找先找到要刪除元素的位置,這樣可以將刪除時間降低到O(logn)。而如果LinkedList是無序的,則只能採用線性查找,刪除時間為O(n)。
// 刪除元素的實現,需要保持LinkedList是有序的
public void delete(int val) {
if (head == null) return;
Node left = head, right = null;
// 找到LinkedList的尾部
while (left != null) {
right = left.next;
left = right != null ? right : null;
}
// 二分查找
left = head;
while (left != right) {
Node mid = left;
int cnt = 0;
// 計算左區間和右區間長度
while (mid != right && cnt = val) {
right = mid;
} else {
left = mid.next;
}
}
// 刪除元素
if (left.val == val) {
Node prev = null, cur = head;
while (cur != left) {
prev = cur;
cur = cur.next;
}
prev.next = left.next;
left.next = null;
}
}
四、是否必須保持有序?
除了上述三個方面的考慮,還有一個更根本的問題,那就是我們是否有必要保持LinkedList的有序性。如果我們的應用場景中,LinkedList的有序性是不必要的,那麼沒有必要犧牲效率去維護它的有序性。反而,如果我們一味地追求有序性,可能會導致我們忽略一些更重要的問題,比如算法的複雜度、空間的利用率等。
總結
LinkedList是一種基本的數據結構,它可以用來表示有序或無序的數據。LinkedList有序還是無序主要取決於我們在插入元素、搜索元素、刪除元素時所採取的策略。具體來說,插入元素的位置與有序性的關係、搜索元素的效率與有序性的關係、刪除元素的效率與有序性的關係都是需要考慮的。然而,我們必須清楚,是否必須保持LinkedList的有序性才是最根本的問題。
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hk/n/186169.html
微信掃一掃
支付寶掃一掃