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