这并不难。考虑递归合并:
+-+-+-+-+-+-+-+-+
| | | | | | | | |
+-+-+-+-+-+-+-+-+
/ \ split
+-+-+-+-+ +-+-+-+-+
| | | | | | | | | |
+-+-+-+-+ +-+-+-+-+
/ \ / \ split
+-+-+ +-+-+ +-+-+ +-+-+
| | | | | | | | | | | |
+-+-+ +-+-+ +-+-+ +-+-+
/ \ / \ / \ / \ split
+-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+
| | | | | | | | | | | | | | | |
+-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+
\ / \ / \ / \ / merge
+-+-+ +-+-+ +-+-+ +-+-+
| | | | | | | | | | | |
+-+-+ +-+-+ +-+-+ +-+-+
\ / \ / merge
+-+-+-+-+ +-+-+-+-+
| | | | | | | | | |
+-+-+-+-+ +-+-+-+-+
\ / merge
+-+-+-+-+-+-+-+-+
| | | | | | | | |
+-+-+-+-+-+-+-+-+
如果你注意到的话,当你分手时,你并没有真正做任何事情。您只需告诉递归函数对数组进行部分排序即可。对数组进行排序首先对两半进行排序,然后将其合并。基本上,你所拥有的是这样的:
+-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+
| | | | | | | | | | | | | | | |
+-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+
\ / \ / \ / \ / merge
+-+-+ +-+-+ +-+-+ +-+-+
| | | | | | | | | | | |
+-+-+ +-+-+ +-+-+ +-+-+
\ / \ / merge
+-+-+-+-+ +-+-+-+-+
| | | | | | | | | |
+-+-+-+-+ +-+-+-+-+
\ / merge
+-+-+-+-+-+-+-+-+
| | | | | | | | |
+-+-+-+-+-+-+-+-+
现在从这里应该很明显了。首先将数组的元素合并为 2 × 2,然后合并 4 × 4,然后合并 8 × 8 等。这就是外部for
给你 2, 4, 8, 16, 32, ...(这就是它所谓的段的大小因为i
循环的包含该数字)和内部for
(用迭代器说j
) 遍历数组,i
by i
合并array[j...j+i/2-1]
with array[j+i/2..j+i-1]
.
我不会编写代码,因为这是家庭作业。
Edit:一张关于内部如何的图片for
works
想象一下如果i
是 4,所以你现在处于这个阶段:
+-+-+ +-+-+ +-+-+ +-+-+
| | | | | | | | | | | |
+-+-+ +-+-+ +-+-+ +-+-+
\ / \ / merge
+-+-+-+-+ +-+-+-+-+
| | | | | | | | | |
+-+-+-+-+ +-+-+-+-+
你将会有一个for
曾经给你0
(这是0*i
) as j
进而4
(这是1*i
) as j
. (if i
是 2,你会j
像 0、2、4、6)
现在,一旦您需要合并array[0..1]
with array[2..3]
(其公式为array[j..j+i/2-1]
and array[j+i/2..j+i-1]
with j = 0
) 进而array[4..5]
with array[6..7]
(由相同的公式制定array[j...j+i/2-1]
and array[j+i/2..j+i-1]
因为现在j = 4
) 那是:
i = 4:
+-+-+-+-+-+-+-+-+
| | | | | | | | |
+-+-+-+-+-+-+-+-+
^ ^ ^ ^ ^ ^ ^ ^
| | | | | | | |
/ / / / \ \ \ \
(j = 0) (j = 4)
| | | | | | | |
j | | | j | | |
| | | j+i-1 | | | j+i-1
| | j+i/2 | | j+i/2
| j+i/2-1 | j+i/2-1
| | | | | | | |
| | | | | | | |
\ / \ / \ / \ /
v v v v
merge merge
希望这一点至少清楚一点。
侧面帮助:如果您真的不知道如何操作,只是一个提示for
works:
for (statement1; condition; statement2)
{
// processing
}
就像写作
statement1;
while (condition)
{
// processing
statement2;
}
所以,如果你总是写
for (int i = 0; i < 10; ++i)
这意味着从0开始,而i
小于 10,做一些事情i
然后递增它。现在如果你愿意i
要改变不同,你只需改变statement2
例如:
for (int i = 1; i < 1024; i *= 2)
(尝试理解最后的结果是如何for
基于其等效项的作品while
我写给你的)