【问题标题】:A simple sorting algorithm一个简单的排序算法
【发布时间】:2017-06-08 15:46:34
【问题描述】:

这是我用Matlab写的一个简单的排序函数:

function [matrix] = sorting(matrix)
    for index = 1:length(matrix)-1
        if matrix(index) > matrix(index + 1)
            temp = matrix(index + 1);
            matrix(index + 1) = matrix(index);
            matrix(index) = temp;
        end
    end
    check_sorted(matrix)
end

function [matrix] = check_sorted(matrix)
    count = 0;
    for index = 1:length(matrix)-1
        if matrix(index) < matrix(index + 1)
            count = count + 1;
        end     
    end

    if count+1 < length(matrix)
         sorting(matrix);
    end
end

sorting 函数的输入是一维数组,例如[4 3 2 1],我第一次调用它成功返回排序数组[1 2 3 4],但是它开始返回未排序数组?

【问题讨论】:

  • 如果发送[2 4 1 3]会怎样?您的排序仅适用于您显示的确切情况,即输入是反向排序的数组。
  • 对不起。我没有意识到 check_sorted 是您排序过程的一部分。

标签: arrays matlab function sorting indexing


【解决方案1】:

您缺少一个分号,导致每次调用check_sorted 的结果都会显示出来,这会造成混乱。如果添加分号,则来自 sorting 的输出以及 cmets 中建议的数组 [2 4 1 3] 为:

>> sorting([2 4 1 3])
ans =

   2   1   3   4

显然这没有排序。问题是 MATLAB 按值而不是按引用传递函数参数。由于您没有从check_sorted 返回重新排序的矩阵或更新sorting 中的返回矩阵,因此原始矩阵永远不会更新。您需要在每个函数中至少更改一行(更改的行已注释):

function [matrix] = check_sorted(matrix)
    count = 0;
    for index = 1:length(matrix)-1
        if matrix(index) < matrix(index + 1)
            count = count + 1;
        end     
    end

    if count+1 < length(matrix)
         matrix = sorting(matrix);   % change: return re-sorted matrix
    end
end


function [matrix] = sorting(matrix)
    for index = 1:length(matrix)-1
        if matrix(index) > matrix(index + 1)
            temp = matrix(index + 1);
            matrix(index + 1) = matrix(index);
            matrix(index) = temp;
        end
    end
    matrix = check_sorted(matrix);   % change: return checked matrix
end

现在,如果矩阵在第一次(或任何后续)传递中未排序,则矩阵将被更新,并且完全排序的矩阵将由 sorting 返回。

这是一种真正没有必要的奇怪递归。如果您将check_sorted 更改为返回布尔值,true 表示已排序,false 表示未排序,您可以将该递归更改为while 循环围绕for 中的for 循环:

function [TF] = check_sorted2(matrix)
    count = 0;
    for index = 1:length(matrix)-1
        if matrix(index) < matrix(index + 1)
            count = count + 1;
        end     
    end

    TF = count+1 == length(matrix);   % TF = true if matrix is sorted
                                      % TF = false otherwise
end


function [matrix] = sorting2(matrix)
   while ~check_sorted2(matrix)   % keep going until matrix is sorted
      for index = 1:length(matrix)-1
         if matrix(index) > matrix(index + 1)
            temp = matrix(index + 1);
            matrix(index + 1) = matrix(index);
            matrix(index) = temp;
         end
      end
   end
end

当然,整个事情都可以进行优化和矢量化,但这至少可以让你继续前进。

【讨论】:

    【解决方案2】:

    我测试了你的算法并且它有效。所以其他事情可能是错的。但是这个算法非常非常低效。你可以谷歌排序并选择一个适合你的。

    如果你真的想坚持这个算法,你可以通过缩短两个循环来改进它。例如,在第一次调用排序之后,对于每个后续调用排序,您可以将循环周期缩短 1,因为第一次调用排序会将最大的数字放在数组的末尾,第二次调用会将第二大的到倒数第二个,以此类推。这就是所谓的冒泡排序。同样在 check_sorted 中,您不需要遍历数组的整个长度来检查数组是否已排序。一旦你看到matrix(index) > matrix(index + 1),你可以立即退出循环(在你设置一个标志来表示数组没有被排序之后)。

    【讨论】:

      最近更新 更多