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-tw/n/186169.html