问题/题干 描述
将一个具有n个元素的数组向左循环移动i个位置。
这只一个很实用的问题,很多应用程序会调用这个问题的算法,例如在文本编辑器中移动行的操作,磁盘整理时交换两个不同大小的相邻内存块等。所有解决这个问题的算法要求有较高的时间性能和空间性能。
解法1
先将数组前i个元素存放于另一个临时数组,再将余下的n-i个元素左移i个位置,最后将前i个元素从临时数组复制会原数组后面i个位置。
总共需要移动i+(n-i)+i=i+n次数组元素,使用了i个额外的存储单元。
解法2
设计一个函数,将数组向左循环1个位置,循环i次。
移动i*n次数组元素,使用了1个额外数组单元。
解法3
换个角度看:
把这个问题看做数组AB转换为数组BA的问题(A代表数组前i个元素,B代表余下n-i个元素)。
先将A取逆得A-1B,再将B取逆得A-1B-1, 最后将整个A-1B-1取逆得BA。
下面通过reverse函数演示一下,对abcdefgh左移3个元素位置:
reverse(0, i-1); cbadefgh
reverse(i, n-1); cbahgfed
reverse(0,n-1); defghabc
该算法总共交换i/2 + (n-i)/2 + n/2 = n次数组元素,使用了1个用来交换的数组单元。
Brian Kernighan 在Software Tools in Pascal中使用了这个算法在文本编辑器中移动各行。