问题:如何交换两段不连续的内存块?
分析篇
这道题是 < 编程珠玑,第二版>第二章后的一个习题。看过这本书的朋友一定会对书中第二章介绍的用来交换两段连续的内存块的"reversal algorithm"一定记忆犹新。"reversal algorithm"无论在时间复杂度还是在空间复杂度上都有良好的表现,更重要的是它的实现相当简单:
1。假设有两段连续的内存块a和b;
2。首先对内存块a进行反转:a' = reverse(a);
3。接着对内存块b进行反转:b' = reverse(b);
3。最后对内存块a'b'进行反转:(a'b')' = ba;
是不是很神奇?当我第一次看到这个算法的时候,我就惊叹为什么这三步简单的操作就能解决看似很复杂的问题?如果你还不相信的话(我一开始和你一样也是不相信),请看下面的例子:
1。假如有两段连续的内存块,a内存块的内容是"abcd",b内存块的内容是"efgh";
2。首先对内存块a进行反转:a' = reverse("abcd") = "dcba";
3。接着对内存块b进行反转:b' = reverse("efgh") = "hgfe";
4。最后对内存块a'b'进行反转:(a'b')' = reverse("dcbahgfe") = efghabcd;
那"reversal algorithm"和本文中需要解决的问题有什么联系呢?在看到这个问题的时候,我就立即联想到了"reversal algorithm",我试图通过已有的方法去解决类似的问题。幸运的是经过简单的分析和推论,我就找到了一个简单的方法,这个方法只要对"reversal algorithm"进行简单的修改就可以解决本文的问题:
1> 假设有三段连续的内存a,b和c,这样a和c是不连续的;
2> 首先对内存块a进行反转:a' = reverse(a);
3> 接着对内存块b进行反转:b' = reverse(b);
4> 接着对内存块c进行反转:c' = reverse(c);
5> 最后对内存块a'bc'进行反转:reverse(a'b'c') = cba;
是不是超简单?这里使用了和"reversal algorithm"一样的思路。最后一次反转,不仅分别将内存块a和c中的数据调整为初始状态,而且还交换它们的位置。由于内存块b处于中间的位置,最后一次反转只将它的内容调整到初始状态。
实现篇
有了上面的分析,编写代码实现这个算法就显得相对比较简单了:
1。首先我们需要一个反转内存块的函数。这个函数应该说比较简单:
分析篇
这道题是 < 编程珠玑,第二版>第二章后的一个习题。看过这本书的朋友一定会对书中第二章介绍的用来交换两段连续的内存块的"reversal algorithm"一定记忆犹新。"reversal algorithm"无论在时间复杂度还是在空间复杂度上都有良好的表现,更重要的是它的实现相当简单:
1。假设有两段连续的内存块a和b;
2。首先对内存块a进行反转:a' = reverse(a);
3。接着对内存块b进行反转:b' = reverse(b);
3。最后对内存块a'b'进行反转:(a'b')' = ba;
是不是很神奇?当我第一次看到这个算法的时候,我就惊叹为什么这三步简单的操作就能解决看似很复杂的问题?如果你还不相信的话(我一开始和你一样也是不相信),请看下面的例子:
1。假如有两段连续的内存块,a内存块的内容是"abcd",b内存块的内容是"efgh";
2。首先对内存块a进行反转:a' = reverse("abcd") = "dcba";
3。接着对内存块b进行反转:b' = reverse("efgh") = "hgfe";
4。最后对内存块a'b'进行反转:(a'b')' = reverse("dcbahgfe") = efghabcd;
那"reversal algorithm"和本文中需要解决的问题有什么联系呢?在看到这个问题的时候,我就立即联想到了"reversal algorithm",我试图通过已有的方法去解决类似的问题。幸运的是经过简单的分析和推论,我就找到了一个简单的方法,这个方法只要对"reversal algorithm"进行简单的修改就可以解决本文的问题:
1> 假设有三段连续的内存a,b和c,这样a和c是不连续的;
2> 首先对内存块a进行反转:a' = reverse(a);
3> 接着对内存块b进行反转:b' = reverse(b);
4> 接着对内存块c进行反转:c' = reverse(c);
5> 最后对内存块a'bc'进行反转:reverse(a'b'c') = cba;
是不是超简单?这里使用了和"reversal algorithm"一样的思路。最后一次反转,不仅分别将内存块a和c中的数据调整为初始状态,而且还交换它们的位置。由于内存块b处于中间的位置,最后一次反转只将它的内容调整到初始状态。
实现篇
有了上面的分析,编写代码实现这个算法就显得相对比较简单了:
1。首先我们需要一个反转内存块的函数。这个函数应该说比较简单:
/**/
//
// swap one adjacent memory block
// The memory layout like this:
// 1--------------|
// | memTotalSize |
// RETURN VALUE: The address of the memory just being swapped
void * swapMemory( void * pMemory,size_t memTotalSize)
... {
if (NULL == pMemory) return pMemory;
if (memTotalSize < 2) return pMemory;
// swap one adjacent memory block
// The memory layout like this:
// 1--------------|
// | memTotalSize |
// RETURN VALUE: The address of the memory just being swapped
void * swapMemory( void * pMemory,size_t memTotalSize)
... {
if (NULL == pMemory) return pMemory;
if (memTotalSize < 2) return pMemory;