插入排序链接列表Java

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了插入排序链接列表Java相关的知识,希望对你有一定的参考价值。

我在下面有这个代码,我将一个新的整数插入到一个有序的LinkedList中,但我不认为这是“正确”的做事方式,因为我知道有一个单独的链表,指针指向下一个值和双链表指向下一个和上一个值的指针。我试图使用Nodes来实现以下情况,但Java正在导入这个导入org.w3c.dom.Node(文档对象模型),所以卡住了。

插入案例

  1. 插入空数组
  2. 如果要插入的值少于所有值,请在开头插入。
  3. 如果要插入的值大于所有值,请插入最后一个。
  4. 如果值小于/大于LL中的某些值,则介于两者之间。 import java.util.*; public class MainLinkedList { public static void main(String[] args) { LinkedList<Integer> llist = new LinkedList<Integer>(); llist.add(10); llist.add(30); llist.add(50); llist.add(60); llist.add(90); llist.add(1000); System.out.println("Old LinkedList " + llist); //WHat if you want to insert 70 in a sorted LinkedList LinkedList<Integer> newllist = insertSortedLL(llist, 70); System.out.println("New LinkedList " + newllist); } public static LinkedList<Integer> insertSortedLL(LinkedList<Integer> llist, int value){ llist.add(value); Collections.sort(llist); return llist; } }
答案

这可能完全符合您的目的:

使用此代码:

import java.util.*;

public class MainLinkedList {
    private static LinkedList<Integer> llist;

    public static void main(String[] args) {
        llist = new LinkedList<Integer>();

        addValue(60);
        addValue(30);
        addValue(10);
        addValue(-5);
        addValue(1000);
        addValue(50);
        addValue(60);
        addValue(90);
        addValue(1000);
        addValue(0);
        addValue(100);
        addValue(-1000);
        System.out.println("Linked List is: " + llist);

    }

    private static void addValue(int val) {

        if (llist.size() == 0) {
            llist.add(val);
        } else if (llist.get(0) > val) {
            llist.add(0, val);
        } else if (llist.get(llist.size() - 1) < val) {
            llist.add(llist.size(), val);
        } else {
            int i = 0;
            while (llist.get(i) < val) {
                i++;
            }
            llist.add(i, val);
        }

    }

}

这个方法将以排序的方式管理List中的插入,而不使用Collections.sort(list)

另一答案

如果我们使用listIterator,那么get的复杂性将是O(1)。

public class OrderedList<T extends Comparable<T>> extends LinkedList<T> {

    private static final long serialVersionUID = 1L;


    public boolean orderedAdd(T element) {      
        ListIterator<T> itr = listIterator();
        while(true) {
            if (itr.hasNext() == false) {
                itr.add(element);
                return(true);
            }

            T elementInList = itr.next();
            if (elementInList.compareTo(element) > 0) {
                itr.previous();
                itr.add(element);
                System.out.println("Adding");
                return(true);
            }
        }
    }
}
另一答案

@Atrakeur

“每次添加新元素时对所有列表进行排序都不高效”

这是真的,但如果您需要列表始终处于排序状态,那么它实际上是唯一的选择。

“最好的方法是将元素直接插入到必要的位置(在正确的位置)。为此,您可以循环所有位置以查找此数字所属的位置”

这正是示例代码所做的。

“或使用Collections.binarySearch让这个高度优化的搜索算法为您完成这项工作”

二进制搜索是有效的,但仅适用于随机访问列表。因此,您可以使用数组列表而不是链接列表,但随着列表的增长,您必须处理内存副本。如果列表的容量高于实际的元素数(这很常见),您还将消耗比您需要的内存更多的内存。

因此,采用哪种数据结构/方法将在很大程度上取决于您的存储和访问要求。

[edit]实际上,示例代码存在一个问题:它在循环时导致列表的多次扫描。

int i = 0;
while (llist.get(i) < val) {
    i++;
}
llist.add(i, val);

对get(i)的调用将遍历列表一次以到达第i个位置。然后对add(i,val)的调用再次遍历它。所以这将非常缓慢。

更好的方法是使用ListIterator遍历列表并执行插入。此接口定义了一个add()方法,该方法可用于在当前位置插入元素。

另一答案

看看com.google.common.collect.TreeMultiset

这实际上是一个排序集,允许多个相同值的实例。

对于您要做的事情,这是一个很好的妥协。插入比ArrayList便宜,但您仍然可以获得二进制/树搜索的搜索优势。

另一答案

链表不是SortedList的更好实现

此外,每次添加新元素时对所有列表进行排序效率不高。最好的方法是将元素直接插入到必要的位置(在正确的位置)。为此,您可以循环所有位置以查找此数字所属的位置,然后插入它,或使用Collections.binarySearch让这个高度优化的搜索算法为您完成此任务。

如果在列表中找到对象,BinarySearch将返回对象的索引(如果需要,可以在此处检查重复项)或( - (插入点) - 1)如果对象未在列表中已经全部(并且插入点是需要放置对象以维护订单的索引)

另一答案

您必须通过了解订单标准来找到插入数据的位置。

简单的方法是强制搜索插入位置(通过列表,二进制搜索...)。

如果您知道数据的性质,另一种方法是估计插入位置以减少检查次数。例如,如果您插入'Zorro'并且列表按字母顺序排列,您应该从列表的后面开始...或估计您的信件可能在哪里(可能在结尾)。如果您知道它们的来源以及它们的分布方式,这也适用于数字。这称为插值搜索:http://en.wikipedia.org/wiki/Interpolation_search

还要考虑批量插入:如果快速插入大量数据,可以考虑一次性进行多次插入,之后只进行一次排序。

另一答案

你可以简单地在log(N)时间复杂度中做到这一点。无需遍历所有值。您可以使用二进制搜索将值添加到已排序的链接列表。只需在该函数的上限位置添加值。检查代码......你可能会更好地理解。

    public static int ubound(LinkedList<Integer> ln, int x) {
        int l = 0;
        int h = ln.size();
        while (l < h) {
            int mid = (l + h) / 2;
            if (ln.get(mid) <= x) l = mid + 1;
            else h = mid;
        }
        return l;
    }

    public void solve() 
    {
        LinkedList<Integer> ln = new LinkedList<>();
        ln.add(4);
        ln.add(6);
        ln.add(ubound(ln, 5), 5);
        out.println(ln);

    }

输出:[4,5,6]

您可以在以下网址了解二进制搜索:https://www.topcoder.com/community/data-science/data-science-tutorials/binary-search/

以上是关于插入排序链接列表Java的主要内容,如果未能解决你的问题,请参考以下文章

如何从片段内的列表视图打开链接网址?

java 147.插入排序列表(#)。java

java 147.插入排序列表(#)。java

java 147.插入排序列表(#)。java

java 147.插入排序列表(#)。java

java 147.插入排序列表(#)。java