如何对 5 个正整数进行排序?

How can I sort 5 positive integers?

我随机收集了 5 个从 1 到 15 的唯一整数,我想按从右到左的升序对它们进行排序。

Example input:  15 6 7 3 4
Desired output: 15 7 6 4 3

规则:

我们一次只能"see" (7 3 4) in (15 6 7 3 4) 中最右边的三个整数,并且只能对数组 (4) 中最右边的整数。我们还可以在代码中使用最多 5 个整型变量。

可能的操作:

putend,最右边的整数放在数组最左边的位置

(15 6 7 3 4) -> (4 15 6 7 3)

swap,最右边的整数和第二个整数交换。 最右边的整数在数组中向左移动一位。

(15 6 7 3 4) -> ( 15 6 7 4 3)

double swap,最右边的整数先和第二个元素交换再和第三个元素交换。 最右边的整数在数组中向左移动 2 步。

(15 6 7 3 4) -> (15 6 4 7 3).


我的尝试:

while (not solved)
  if first element < 2nd element
    putend
  else if first element > 2nd element
    if first element > 3rd element
        double swap
    else
      swap

输出:

15 6 7 3 4  swap
15 6 7 4 3  putend
3 15 6 7 4  putend
4 3 15 6 7  swap
4 3 15 7 6  putend
6 4 3 15 7  putend
7 6 4 3 15 (problem here, triggers double swap but want putend and somehow detect that I am done)

我创建了一个工作 Python 程序来演示算法,但我认为它对每个人来说都像伪代码一样可读(我使代码非常简单)。解决方案非常残酷,但似乎有效。还有很多进一步优化的潜力。我把描述放在评论中:

x = [15, 12, 3, 2, 13]

def putend():
    x.append(x.pop(0))

def swap():
    x[0], x[1] = x[1], x[0]

def doubleswap():
    x[0], x[1], x[2] = x[1], x[2], x[0]


def put_smallest_back():
  smallest = min(x[0], x[1], x[2])
  if x[2] == smallest:
    # Move smallest to x[1]
    doubleswap()
  if x[1] == smallest:
    # Move smallest to x[0]
    swap()
  putend()

# Put back two smallest values of four to make sure two largest are in front
put_smallest_back()
put_smallest_back()

# Now two largest values are in three accessible cells
# Find and put back second largest
largest = max(x[0], x[1], x[2])
smallest = min(x[0], x[1], x[2])
if x[2] != largest and x[2] != smallest:
  doubleswap()
if x[1] != largest and x[1] != smallest:
  swap()
putend()

# Find and put back largest
# Largest is in x[0] or x[1]
if x[1] == largest:
  swap()

# Largest is in x[0]
putend()

# Two largest values are sorted
# Time to sort x[2]
if x[0] > x[1] and x[0] > x[2]:
  doubleswap()
elif x[1] > x[0] and x[1] > x[2]:
  swap()
  doubleswap()

# Last step, sort x[0] and x[1]
if x[0] > x[1]:
  swap()

# Voilla!
print(x)

我使用了 min()max() 函数但没有定义它们,但是它们的实现很简单,尤其是它们总是对集合的前三个元素进行操作。

这是另一种解决方案。这次我创建了一个 sort3() 实用函数来对前三项进行排序。这种大大简化的算法现在不需要 min()max() 或任何其他变量。解决方案是功能齐全的 Python 代码,但与伪代码一样易于阅读:

x = [5, 1, 13, 2, 10]

def putend():
    x.append(x.pop(0))

def swap():
    x[0], x[1] = x[1], x[0]

def doubleswap():
    x[0], x[1], x[2] = x[1], x[2], x[0]

# Sort first 3 elements ascending
def sort3():
    if x[1] > x[0]:  # Ensure larger of first two is x[0]
        swap()
    if x[0] > x[2]:  # If x[0] is largest, doublewsap it to x[2]
        doubleswap()
    if x[0] > x[1]:  # Largest value is in x[2], sort x[0] and x[1]
        swap()

# Put back smallest of first three items
sort3()
putend()

# Put back smallest of first three items again (x[2] is new item)
sort3()
putend()

# Now two largest values are in first three cells
# Find and put back second largest value
sort3()
swap()
putend()

# Put largest back
swap()
putend()

# Two largest values are sorted
# Time to sort the rest
sort3()

# Voila!
print(x)