按照最频繁发生的顺序排序稍微洗牌的列表

时间:2016-10-07 16:30:14

标签: sorting

我们假设您有一个项目列表,这些项目处于轻微的混乱状态"。在他的例子中,Blue主要是 ,Red在中间是 ,而底部是

Blue
Blue
Blue
Red
Blue
Green
Red
Red
Red
Blue
Green
Green
Green
Blue

是否有算法:嗯,大部分蓝色都在开头,所以我们先把它们放在首位。大部分红色位于中间位置,所以它们接下来,依此类推,产生以下输出:

Blue
Blue
Blue
Blue
Blue
Blue
Red
Red
Red
Red
Green
Green
Green
Green

或者只是:

Blue
Red
Green

2 个答案:

答案 0 :(得分:1)

我不确定现有算法,但是为了弄清楚元素的顺序,你可以计算X元素在Y元素之前的次数,反之亦然。如果X在Y之前出现超过Y在X之前出现,则首先排序X(对于所有X / Y对)。效率非常低(多项式时间),但这可能是制作更好算法的良好开端。

例如,在以下列表中。 。

Red
Red
Blue

。 。 。每个红色来自蓝色(总共两个),而蓝色不会出现在任何红色之前(总共为零),所以先订购红色。

有时候没有优先权,例如以下列表。 。

Red
Blue
Blue
Red

。 。 。由于红色出现在两个蓝色(总共两个)之前,并且每个蓝色出现在红色之前(总共两个),因此该算法不会优先。

为了使其效率更高并且可能更适合您的模型,请预处理列表以使用其计数折叠连续元素。例如以下列表

Red
Red
Red
Red
Red
Blue
Blue
Red

可以表示为

Red (5)
Blue (2)
Red (1)

现在,您可以将计算乘以元素数。在上面,5个红色在2个布鲁斯之前出现,所以在布鲁斯之前有10个红色。同样地,2个蓝色在1个红色之前出现,因此在红色之前有2个蓝色。所以我们先订购Reds。

同样的想法被扩展到包括两个以上不同的元素。

答案 1 :(得分:-1)

尝试快速排序:

public class Quick
{
    private static int partition(Comparable[] a, int lo, int hi)
    {
        int i = lo, j = hi+1;
        while (true)
        {
        while (less(a[++i], a[lo])) if (i == hi) break;
        while (less(a[lo], a[--j])) if (j == lo) break;
        if (i >= j) break;
        exch(a, i, j);
        }
    exch(a, lo, j);
    return j;
    }
    private static void sort(Comparable[] a, int lo, int hi)
    {
        if (hi <= lo) return;
        int j = partition(a, lo, hi);
        sort(a, lo, j-1);
        sort(a, j+1, hi);
    }
}

来源:http://algs4.cs.princeton.edu/23quicksort/Quick.java