Lua 中的冒泡排序算法无法工作

我目前正在学习 Lua,并试图使用它创建一个冒泡排序算法。但我无法让它正常工作。有没有人能够指出为什么?

我可以指出一些细节,比如在像列表这样的较短列表上,算法确实可以成功地对其进行排序,但然后继续对其进行排序,好像它没有被排序一样。在像列出 5 个元素这样的更长的列表上,程序根本不会对其进行排序。我通过让程序每次交换两个元素时打印列表来获取这些信息。

user_input = 0
list = {}

while user_input ~= "SORT" do
  print("输入数字值,或输入 SORT 进行排序")
  user_input = io.read()
  if user_input ~= "SORT" then
    table.insert(list, user_input)
  end
end

done = false
while done == false do
  done = true
  for k, v in pairs(list) do
    if k ~= 1 then
      if list[k] < list[k - 1] then
        list[k], list[k - 1] = list[k - 1], list[k]
        done = false
        for k, v in pairs(list) do
          io.write(v .. " ")
        end
        print()
      end
    end
    if k == 1 then
      if list[k] < list[table.maxn(list)] then
        list[k], list[table.maxn(list)] = list[table.maxn(list)], list[k]
        done = false
        for k, v in pairs(list) do
          io.write(v .. " ")
        end
        print()
      end
    end
  end
end

io.write("RESULT: ")
for k, v in pairs(list) do
  io.write(v .. " ")
end
print()
点赞
用户7396148
用户7396148

在 Lua 中,有两个函数可以创建表的迭代器pairsipairs

使用pairs,产生的顺序是不确定的,它将返回所有的键值对,但无法保证顺序。

  • 您可以在 Lua 5.1 的参考手册中找到 next
  • 例如:{1,2,3,4,5}的输出可能是5,2,4,1,3

ipairs的顺序是从1到第一个nil,它不会返回任何非整数键。

  • 例如:{1,2,3,nil,5}将给你1,2,3

使用pairs,您的算法输出可能是正确的,但由于pairs的顺序而出现错误。 因此,您应该使用ipairs来评估您的算法输出,以便通过索引排序。


现在,您的算法不会执行冒泡排序,如果您想,我可以为此提供更正。 为了这个初始答案,我认为澄清会创建不一致输出的内容应该指向正确的方向。

冒泡排序应该“一次”对1个索引进行排序,第一次通过将排列数组的最后一个值。 然后每次通过排序以下位置。 例如:

  • 在第一次通过2,1,3,4,5,8,7,6 之前
  • 在第一次通过1,2,3,4,5,7,6,8之后

维基百科有各种排序算法的非常好的页面,其中包含可以真正帮助理解其如何运作的 gif 图像:冒泡排序

2020-11-23 19:39:36
用户3342050
用户3342050

你正在使用pairs()而不是ipairs()。此外,你的代码有一个不必要的maxn()例程。

#! /usr/bin/env lua

local user_input = 0
local list = {}

while user_input ~= 'sort' do
    print('输入数字值,或输入SORT开始排序')
    user_input = io.read():lower()
    -- 'sort'这个单词不返回数字,因此没有最终插入
    table.insert(list, tonumber(user_input))
end

local found_swap = true
while found_swap do
    found_swap = false
    for i = 2, #list do
        if list[i] < list[i-1] then
            list[i], list[i-1] = list[i-1], list[i]
            found_swap = true
        end
    end
end

io.write('RESULT: ')
for i, v in ipairs(list) do
    io.write(v .. ' ')
end
print()
2020-11-23 19:55:52
用户10480373
用户10480373

下面是我的实现方法,几点说明:

我的 Lua 版本(Luau)支持类型检查等功能,所以你可能需要从参数中删除 : table。(如果你想了解更多关于 Luau 的信息,请访问此链接:https://roblox.github.io/luau/ - 很酷的)

local function bubbleSort(t: table)
    local function check(i, v)
        local nextNum = t[i+1]
        if nextNum and (nextNum < v) then
            t[i] = nextNum
            t[i + 1] = v

            return true
        end
    end

    local changeMade
    repeat
        changeMade = false
        for i, v in next, t do
            changeMade = check(i, v) or changeMade
        end
    until changeMade == false
end

local tableForSorting = {2,5,4} --2,4,5
bubbleSort(tableForSorting)
print(tableForSorting)

希望这能有所帮助,并展示如何将代码库精简化并且仍然正常工作!你的代码没有正常工作的原因,正如其他人所说,pairs() 不能保证以一致的方式对列表进行排序。

实践中,我们使用 pairs() 处理 _字典_,而使用 ipairs() 处理数组。你会注意到我在这个例子中使用了 next,它与 ipairs() 完全相同。如果您有任何后续问题,请在下面留言! :)

2021-02-15 21:09:27