惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

H
Help Net Security
腾讯CDC
爱范儿
爱范儿
Google DeepMind News
Google DeepMind News
V
V2EX
Blog — PlanetScale
Blog — PlanetScale
Engineering at Meta
Engineering at Meta
GbyAI
GbyAI
量子位
F
Fortinet All Blogs
G
Google Developers Blog
T
The Blog of Author Tim Ferriss
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Hugging Face - Blog
Hugging Face - Blog
Last Week in AI
Last Week in AI
T
Tailwind CSS Blog
J
Java Code Geeks
S
SegmentFault 最新的问题
D
Docker
博客园 - 司徒正美
The GitHub Blog
The GitHub Blog
Jina AI
Jina AI
M
MIT News - Artificial intelligence
博客园 - 【当耐特】

The Old New Thing

Why didn't Read­Directory­ChangesW provide a way to correlate the two sides of a rename operation? - The Old New Thing How can I remove the Close button from my window caption? - The Old New Thing Why is the x86 undefined instruction called ud2? Why 2? - The Old New Thing What algorithm did Windows XP use to choose your initial user picture? - The Old New Thing A sample use of the winstart.bat file in Windows 95 - The Old New Thing Why don't we allow stacks to be sparse, instead of forcing them to be contiguous? - The Old New Thing What happens if you change a window class's GCL_CB­WND­EXTRA? - The Old New Thing The case of the progress callback that never got called when progress happened - The Old New Thing The perils of binding to value types in XAML - The Old New Thing Microspeak: Funded / unfunded - The Old New Thing AWE does not require PAE, though PAE makes it much more useful - The Old New Thing On forcing all derived classes to implement a specific non-virtual method, part 2 - The Old New Thing On forcing all derived classes to implement a specific non-virtual method, part 1 - The Old New Thing In the product end game, every change carries significant risk, episode 2 - The Old New Thing Why didn't the Windows Entertainment Pack just run the MS-DOS version inside an emulator? - The Old New Thing Comparing the two holograms on the Windows 95 box - The Old New Thing Reducing C++ template bloat by factoring out the type-dependent portions of the function, practical exam - The Old New Thing Reducing C++ template bloat by factoring out the type-dependent portions of the function - The Old New Thing On wrapping a callable in a lambda that just calls it with the same parameters - The Old New Thing Why did the Microsoft Entertainment Pack for Windows have a special sticker announcing that it also had Tetris? - The Old New Thing How do functions like alloca allocate memory from the stack? - The Old New Thing How do functions like alloca allocate memory from the stack? - The Old New Thing Forcing an ARM64X executable to run as a specific architecture - The Old New Thing A little helper class for managing LPPROC_THREAD_ATTRIBUTE_LISTs - The Old New Thing The comments that go into code versus those that go into the pull request description - The Old New Thing The little-known winstart.bat batch file - The Old New Thing How can I perform a Copy­File&shy in unbuffered mode? - The Old New Thing Creating a fake agile wrapper that is technically agile but is not useful outside its home apartment, part 5 - The Old New Thing Creating a fake agile wrapper that is technically agile but is not useful outside its home apartment, part 4 - The Old New Thing Creating a fake agile wrapper that is technically agile but is not useful outside its home apartment, part 3 - The Old New Thing
Rotation revisited: Shuffling more than three blocks, and...
Raymond Chen · 2026-06-08 · via The Old New Thing

A few small notes on rotation before you get sick of it. (Too late!)

Reducing the number of rotations in the discontiguous swap problem from three to two also shows how the solution can be generalized to shuffling an arbitrary number of variable-sized blocks: Given k blocks, of total size n, you can shuffle them arbitrarily in at most kn swaps in constant space: Take the block that goes first and rotate it to the front, which takes n swaps. Then recurse on what’s left.

You can reduce the number of swaps by comparing the sizes of the block that goes first and the block that goes last and choose to swap the larger block to the corresponding extreme.

I guess you could use this for sorting, but it’s probably enough of a hassle that you’ll just take the penalty of allocating a second block of memory rather than trying to be clever and doing it in-place.

In online discussion of this article, I saw a number of people say, “You can do this with the XOR trick,” but I’m not sure what XOR trick they are referring to. If they are talking about using XOR to swap two integer variables without introducing a third variable, that’s a cute trick I don’t see how it helps with moving variable-sized blocks around. It also doesn’t help with swapping non-integers, since it’s not clear how your XOR two strings or two Widgets.

Another note is that my unit of accounting was the “swap”, but really I should be counting “assignments” because the cycle decomposition algorithm doesn’t use swaps. For the purpose of accounting, I’ve been counting a single assignment as half a swap, though depending on how expensive the move constructor is, a single assignment/construction might only cost a third of a swap.

Finally, a clarification on my description of the solution as “constant space without allocation”: Clearly any algorithm requires some space: space for the parameters, return address, any registers used by the code, and any local variables and temporaries. As long as the number and size of these things is bounded by a constant, this is considered a “constant space” algorithm. Note that the size of an element is not known to the generalized algorithm, but once you implement the algorithm for a concrete element type, the size becomes a constant.

My description of this as “without allocation” is a shorthand for “without requiring dynamic memory allocation (because the amount of memory needed is known at compile time).”

I have a soft spot for algorithms that run in constant space (where the constant is reasonably small) because they remove the need to worry about how to recover if there is a memory allocation failure.

Category

Topics

Author

Raymond Chen

Raymond has been involved in the evolution of Windows for more than 30 years. In 2003, he began a Web site known as The Old New Thing which has grown in popularity far beyond his wildest imagination, a development which still gives him the heebie-jeebies. The Web site spawned a book, coincidentally also titled The Old New Thing (Addison Wesley 2007). He occasionally appears on the Windows Dev Docs Twitter account to tell stories which convey no useful information.