将值插入已排序的数组中

时间:2013-11-08 13:29:32

标签: python algorithm list sorting insert

在排序的numpy数组中将值插入正确位置的最快方法是什么?

例如,我想将b的每个值插入a

a = [1,1,2,4,7,7,11,13,13,13,15,20,25,26,27,30,45,70]

b = [5,7,9,45]

我已尝试为a的每个值循环遍历b并以此方式插入。我也尝试了bisect_left方法:

for i in b:
a.insert(bisect_left(a,i),i)

这两种方法都太慢了,因为我需要经过数十万个数据元素。

有什么想法吗?

5 个答案:

答案 0 :(得分:3)

让我们注意n = len(a) and m = len(b)

  1. 您可以使用二进制搜索来查找每个元素的位置并插入它, 这将在 m * n * log(n)时间
  2. 中完成
  3. 您可以合并两个阵列,这将具有n + m复杂度
  4. 你可以使用一个专门的结构,一个平衡的二叉树,你可以在python中找到很多这些实现,时间复杂度将是 mlog(n)
  5. 现在给出n和m的可能值,你可以确定哪种解决方案最好,但不要期望做得更好

答案 1 :(得分:2)

只需使用内置sort方法。它实现了timsort。如果列表几乎已经排序,那么速度非常快。

a.extend(b)
a.sort()

答案 2 :(得分:2)

对于更 Pythonic 的方法,您可以使用 bisect.insort(your_list, your_value) 将值插入到排序列表的正确位置。像这样:

import bisect

a = [1,1,2,4,7,7,11,13,13,13,15,20,25,26,27,30,45,70]
b = [5,7,9,45]

for value in b:
    bisect.insort(a, value)

# Now a == [1, 1, 2, 4, 5, 7, 7, 7, 9, 11, 13, 13, 13, 15, 20, 25, 26, 27, 30, 45, 45, 70]

答案 3 :(得分:0)

您可以使用searchsortedinsert

a = numpy.array([1,1,2,4,7,7,11,13,13,13,15,20,25,26,27,30,45,70])
b = numpy.array([5,7,9,45])
ii = numpy.searchsorted(a, b)
a = numpy.insert(a, ii, b)

答案 4 :(得分:-1)

你的解决方案很慢,因为你有很多插入。每个insrt都是O(N)复杂度。

我的解决方案: a = [1,1,2,4,7,7,11,13,13,13,15,20,25,26,27,30,45,70] b = [5,7,9,45]

将b.Length项插入到a的末尾。 a = [1,1,2,4,7,7,11,13,13,13,15,20,25,26,27,30,45,70,x,x,x,x] b = [5,7,9,45]

三点:

  1. 指向 a 指向上一个实际元素(指向 70 的示例指针)
  2. 指向 b 指向最后一个元素(指向 45 的示例指针)
  3. 指向a
  4. 的最后一个

    这是我在C#中的解决方案:

        int p1 = a.Length - 1;
        int p2 = b.Length - 1;
        int p3 = a.Length + b.Length - 1;
    
        //Insert b.Length items to end of a.
    
        while (p3 >= 0 && p2 >= 0)
        {
            if (p1 < 0 || b[p2] >= a[p1])
            {
                a[p3--] = b[p2--];
            }
            else
            {
                a[p3--] = a[p1--];
            }
        }