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
微信扫一扫
支付宝扫一扫