我试图理解为什么heapsort不稳定.我用Google搜索了这个,但没有找到一个好的,直观的解释.
我理解稳定排序的重要性 - 它允许我们基于多个键进行排序,这可能是非常有益的(即,进行多个排序,每个排序基于不同的键.因为每种排序都将保留元素的相对顺序,以前的排序可以加起来给出按多个标准排序的元素的最终列表.但是,为什么heapsort也不会保留这个呢?
谢谢你的帮助!
我按特定顺序拥有ID
>>> album_ids = [24, 15, 25, 19, 11, 26, 27, 28]
>>> albums = Album.objects.filter( id__in=album_ids, published= True )
>>> [album.id for album in albums]
[25, 24, 27, 28, 26, 11, 15, 19]
Run Code Online (Sandbox Code Playgroud)
我需要查询集中的相册作为album_ids中的id.有人请告诉我如何维护订单?或获取专辑中的专辑?
我试图理解这篇论文:线性时间内稳定的最小空间划分.
似乎这个主张的一个关键部分是
算法B在 O(nlog 2 n)时间和恒定的额外空间中稳定地排序大小为n的位数组,但仅使O(n)移动.
但是,本文没有描述算法,只引用了另一篇我无法访问的论文.我可以找到几种方法在时间范围内进行排序,但是我很难找到一个保证O(N)移动而不需要超过恒定空间的方法.
这个算法B是什么?换句话说,给定
boolean Predicate(Item* a); //returns result of testing *a for some condition
Run Code Online (Sandbox Code Playgroud)
是有一个功能B(Item* a, size_t N);,其稳定地排序一个使用谓词如少于NLOG排序键2个 n次呼叫到谓词,只有O(N)写入到执行一个?
假设我的输入是(a,b并c区分相等的键)
1 6a 8 3 6b 0 6c 4
Run Code Online (Sandbox Code Playgroud)
我计数排序将保存为(丢弃a,b而c信息!)
0(1) 1(1) 3(1) 4(1) 6(3) 8(1)
Run Code Online (Sandbox Code Playgroud)
这将给我结果
0 1 3 4 6 6 6 8
Run Code Online (Sandbox Code Playgroud)
那么,这种稳定的排序如何?我不确定它是如何"用相同的键保持记录的相对顺序".
请解释.
我想利用std::stable_sort.算法的复杂性表示为
O(N·log ^ 2(N)),其中N = std :: distance(first,last)cmp的应用.如果有额外的内存,则复杂度为O(N·log(N)).http://en.cppreference.com/w/cpp/algorithm/stable_sort
在我的申请中,存储器是至关重要的,因此,我宁愿std::stable_sort使用存储器优化的O(N·登录^ 2(N))的算法,而不是时间优化O(N·日志(N))的算法.我知道只有在安全的情况下才会选择时间优化版本(可用内存).但是,我的目标是对我的应用程序进行基准测试,因此,当内存非常重要时,需要在内存消耗最低时对算法进行基准测试.由于我的系统目前有足够的内存来分配缓冲区,它会自动选择O(N·log ^ 2(N))版本std::stable_sort.因此,我想主张std::stable_sort采用内存优化版本.这可能吗?
执行策略似乎是可以修改算法的参数,但是,它似乎只会改变并行度. http://en.cppreference.com/w/cpp/algorithm/execution_policy_tag_t
虽然选择并行或顺序版本实际上可能实际上分别选择O(N·log(N))或O(N·log ^ 2(N))版本,但这在网页上的任何地方都没有说明.
我想知道是否有人有任何断言这种选择的经验.如果是这样他们能提供任何建议吗?
我假设stdlib中的旧的qsort函数不稳定,因为手册页没有说明任何内容.这是我正在谈论的功能:
#include <stdlib.h>
void qsort(void *base, size_t nmemb, size_t size,
int(*compar)(const void *, const void *));
Run Code Online (Sandbox Code Playgroud)
我假设如果我改变我的比较函数也包括我正在比较的地址,它将是稳定的.那是对的吗?
例如:
int compareFoos( const void* pA, const void *pB ) {
Foo *pFooA = (Foo*) pA;
Foo *pFooB = (Foo*) pB;
if( pFooA->id < pFooB->id ) {
return -1;
} else if( pFooA->id > pFooB->id ) {
return 1;
} else if( pA < pB ) {
return -1;
} else if( pB > pA ) {
return 1;
} else {
return …Run Code Online (Sandbox Code Playgroud) 我使用TList/TObjectList和TStringList(带有关联对象)来执行大量任务,既可以是原样,也可以作为更复杂结构的基础.虽然排序功能通常足够好,但我有时需要进行稳定排序,两个列表都使用快速排序.
为TList和/或TStringList实现稳定排序的最简单方法是什么?我是否必须编写自己的排序例程,还是可以通过TStringListSortCompare/TListSortCompare使用一些聪明的技巧来完成?
这是关于对术语的特定参数进行排序的问题的答案的后续,而没有为a创建新列表keysort(如果我正确理解原始问题).
假设我们想predsort/3表现得如下sort/2:如果我理解正确,这将意味着将其称为:
?- predsort(compare, List, Sorted).
Run Code Online (Sandbox Code Playgroud)
现在说我们想用它predsort/3来实现排序msort/2(参见这个问题).一种方法是定义一个比较谓词Pred(-Delta, +A, +B),它不Delta与=元素实际上相等的时候统一:
mcompare(Delta, A, B) :-
compare(Delta0, A, B),
( Delta0 == (=)
-> Delta = (<)
; Delta = Delta0
).
?- predsort(mcompare, List, Sorted).
Run Code Online (Sandbox Code Playgroud)
问题:这是否真的只是排序而不删除重复项,就像msort/2这样做?好像应该这样.
继续:说我们想要按照术语中第n个参数的标准顺序对arity> n进行排序.干净的方法是:
sort_argn(N, List, Sorted) :-
map_list_to_pairs(arg(N), List, Pairs),
keysort(Pairs, Sorted_pairs),
pairs_values(Sorted_pairs, Sorted).
Run Code Online (Sandbox Code Playgroud)
如果我们想用来predsort/3达到相同的效果,我们可以尝试使用比较谓词,如下所示:
compare_argn(N, Delta, A, B) :-
arg(N, A, …Run Code Online (Sandbox Code Playgroud)