【问题标题】:Insertion sort in python with negative numbers at the end of the listpython中的插入排序,列表末尾有负数
【发布时间】:2018-11-19 16:05:29
【问题描述】:

我使用排序算法对数字进行排序,例如正数,然后是负数(就地交换,您可以使用变量,但不使用任何容器变量。假设我们没有更多的内存空间对于额外的容器)。所以先排序正数,再排序负数。

我做到了,但我需要另一个 for 循环来对负数进行排序并将它们插入到列表的末尾。

我的问题:有没有办法修改第一个循环以达到相同的结果? (即:仅使用 1 个for 循环)

例如:

x = [9, -3, 2, -7, -4, -1, 5, 4]

输出应该是:

[2, 4, 5, 9, -7, -4, -3, -1]

这是我的解决方案(但我使用了 2 个 for 循环,我只想使用 1 个):

def insertion_sort(data):
    for i in range(1, len(data)):
        e = i
        while e > 0 and data[e - 1] > data[e]:
            data[e - 1], data[e] = data[e], data[e - 1]
            e -= 1
    for i in range(1, len(data)):
        e = i
        while e > 0 and data[e - 1] < 0:
            if data[e] < 0:
                if data[e - 1] < data[e]:
                    data[e - 1], data[e] = data[e], data[e - 1]
            data[e - 1], data[e] = data[e], data[e - 1]
            e -= 1
    print(data)

【问题讨论】:

  • 您是否考虑过进行正常的插入排序,然后找到列表从负数变为正数的索引,然后重新切片列表?该算法仍将受到排序的限制。
  • 是的,这个想法很好,但是重新切片列表意味着使用额外的列表(我在我的问题中说不要使用任何额外的容器,只需在适当的位置交换元素)

标签: python python-3.x sorting


【解决方案1】:

你可以定义一个函数is_greater如下:

def is_greater(x, y):
    if (x < 0 and y < 0) or (x >= 0 and y >= 0):
        return x > y
    return x < 0

然后你可以在你的第一个循环中使用它而不是普通的 int 比较:

def insertion_sort(data):
    for i in range(1, len(data)):
        e = i
        while e > 0 and is_greater(data[e - 1], data[e]):
            data[e - 1], data[e] = data[e], data[e - 1]
            e -= 1
    print(data)

insertion_sort(d)

输出

[2, 4, 5, 9, -7, -4, -3, -1]

【讨论】:

  • 是的,谢谢@slider,这是一个很好的方法。您没有使用任何额外的容器(可迭代)。您只是将它们交换到位。很好的解决方案
  • 但我希望我能找到一个没有额外功能的解决方案。就像修改只有 for 循环来完成这项工作一样
【解决方案2】:

您只需要在数字开始为正数时找到枢轴值

def insertion_sort(data):

    pivot = -1
    for i in range(1, len(data)):
        e = i
        while e > 0 and data[e - 1] > data[e]:
            data[e - 1], data[e] = data[e], data[e - 1]
            if data[e] >= 0 and data[e-1] < 0:
                pivot = e
            e -= 1

    data[-pivot:], data[:-pivot] = data[:pivot], data[pivot:]
    print(data)

【讨论】:

  • 感谢@Hemerson Tacon,但您不符合我的要求。我说过要使用任何额外的容器变量,但是您使用了具有列表值的 neg 变量。我想要一个只是“就地”交换元素的解决方案。但是感谢您的尝试
  • @FouadDev 刚刚修复了代码,它有一些错误,现在我不再使用额外的容器了
  • 由于负值从列表末尾向后索引,因此可以简化最后一行。
  • @FouadDev 你能定义你所说的容器吗?因为我的解决方案的最后一行将值交换到位,就像在 for 中所做的一样
  • 是的@Hemerson Tacon 这实际上是一个很好的解决方案。干得好人
猜你喜欢
  • 2013-10-30
  • 2017-09-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-02
  • 1970-01-01
  • 2015-05-14
  • 2015-11-21
  • 1970-01-01
相关资源
最近更新 更多