【问题标题】:Stable implementation of Stooge Sort?Stooge Sort 的稳定实现?
【发布时间】:2012-05-13 20:31:12
【问题描述】:

这真的可能吗?我在维基百科中找到了它,但我还不能完美地可视化这个过程,所以我不知道我必须改变什么才能使其稳定。

【问题讨论】:

    标签: algorithm


    【解决方案1】:

    任何基于比较的排序算法都可以变得稳定。只需更改比较函数,如果两个元素相等,它就会比较它们的 original 索引。由于 stooge 排序是基于比较的排序,因此也可以在此处应用。

    【讨论】:

    【解决方案2】:

    首先,请注意Stooge Sort 只有一个步骤实际上改变了元素的顺序:第一个。剩下的步骤都是递归步骤。更改任何递归步骤都会改变算法的基本特征,因此如果我们不以这种方式递归,它将不再是走狗(这三个递归调用似乎是典型的“走狗”。)

    第一步也很简单,改变它似乎也改变了算法的特性。但是我们可以对其进行调整:如果初始元素大于最终元素,则将等于最终元素的第一个元素 AA 之前的最后一个元素交换em> 等于初始元素,我们可以通过单遍找到它。令人惊讶的是,即使内部循环现在是 O(n) 而不是 O(1),Master theorem 向我们展示了复杂性在 O(n ^2.71)。同样,如果所有元素都是唯一的,则会发生与原始 Stooge Sort 中相同的交换序列,这使得该版本成为近亲。

    为了快速概括为什么这个版本是稳定的,可以考虑将两个相等的元素重新排序为“错误交换”。我们声称使用上述方法没有坏掉期。原因是对于任何交换,我们知道两个元素之间没有元素等于任何一个元素。由于相等的元素保持相同的顺序,因此算法是稳定的。

    算法正确的证明类似于原始Stooge Sort的正确性证明。这是一个常见的家庭作业问题,所以我不想放弃它,但它来自归纳假设。

    如果调整的描述有点简洁,下面是 Java 实现。

    import java.util.Arrays;
    import java.util.Random;
    
    public class StableStooge {
        public static class FooBar implements Comparable<FooBar> {
            public final int foo;
            public final int bar;
    
            public FooBar(int foo, int bar) {
                this.foo = foo;
                this.bar = bar;
            }
    
            @Override
            public int compareTo(FooBar arg0) {
                return foo - arg0.foo;
            }
    
            public String toString() {
                return foo +":"+bar;
            }
        }
    
        private static void sort(Comparable[] c, int start, int end) {
            if (start >= end) return;
            if (c[start].compareTo(c[end]) > 0) {
                // Find the first thing X equal to end and the last thing Y which is before X and equal to start
                int lastindex = end;
                int firstindex = start;
                for (int i = start + 1; i < end; i++) {
                    if (c[end].compareTo(c[i]) == 0) {
                        lastindex = i;
                        break;
                    } else if (c[start].compareTo(c[i]) == 0) {
                        firstindex = i;
                    }
                }
                Comparable tmp = c[firstindex];
                c[firstindex] = c[lastindex];
                c[lastindex] = tmp;
            }
            // Recurse
            if (end - start + 1 >= 3) { 
                int third = (end - start + 1) / 3;
                sort(c, start, end-third);
                sort(c, start+third, end);
                sort(c, start, end-third);
            }
        }
    
        public static void sort(Comparable[] c) {
            sort(c, 0, c.length-1);
        }
    
        public static void main(String[] args) {
            FooBar[] test = new FooBar[100];
            FooBar[] testsav = new FooBar[100];
            Random r = new Random();
            for (int i = 0; i < 1000; i++) {
                for (int j = 0; j < test.length; j++) {
                    test[j] = new FooBar(r.nextInt(10), j);
                    testsav[j] = test[j];
                }
                sort(test);
                // verify
                for (int j = 1; j < test.length; j++) {
                    if (test[j].foo < test[j-1].foo) {
                        throw new RuntimeException("Bad sort");
                    }
                    if (test[j].foo == test[j-1].foo && test[j].bar <= test[j-1].bar) {
                        throw new RuntimeException("Unstable sort: "+Arrays.toString(testsav)+" sorted improperly to "+Arrays.toString(test));
                    }
                }
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2010-10-11
      • 2013-12-11
      • 2017-04-21
      • 1970-01-01
      • 2018-03-22
      • 2012-07-06
      • 1970-01-01
      • 2014-08-03
      • 1970-01-01
      相关资源
      最近更新 更多