1.3 一摞烙饼的排序

1.3 一摞烙饼的排序

参考《编程之美–1.3 一摞烙饼的排序》
问题描述:
一摞乱序摆放的烙饼,每次只能抓取最上面几块烙饼并翻转,多次翻转后能够实现烙饼的从小到大(从上往下)的有序摆放。
问题分析:
这里我们使用回溯法解决这个问题。直接用回溯法效率是低下的,因此要进行剪枝。这里的剪枝条件是利用翻转次数的上界和下界完成的。
上界:
[4,2,1,5,3] -> [5,1,2,4,3] -> [3,4,2,1,5]
两步可以按大小顺序将某块饼放到它应该在的位置。
同理,可以把其他四块烙饼摆放好,要注意最后一块烙饼会在最后第二块烙饼摆放正确后位于正确位置。假设烙饼个数为n,则翻转次数上界为2(n-1)。
下界:
上界我们已经得出了,下面考虑下界。在试验翻转的时候,我们可以发现,当烙饼堆部分有序时,翻转次数较少。若一摞烙饼中有m对相邻的烙饼半径不相邻,理想情况下需要m次翻转来排序,[3,4,2,1,5,6],此时就需要两次来翻转。

代码如下:

#include 
#include 
#include 
#include 

using namespace std;

class PreFixSorting
{
public:
    PreFixSorting()
    {
        CakeCount = 0;
        MaxSwap = 0;
    }

    ~PreFixSorting()
    {
        if(CakeArray != NULL)
        {
            delete CakeArray;
        }
        if(SwapArray != NULL)
        {
            delete SwapArray;
        }
        if(ReverseCakeArray != NULL)
        {
            delete ReverseCakeArray;
        }
        if(ReverseCakeArraySwap != NULL)
        {
            delete ReverseCakeArraySwap;
        }
    }

    //计算烙饼翻转信息
    //@param
    //pCakeArray    存储烙饼索引数组,索引大的烙饼个头大
    //pCakeCount    烙饼个数

    void Run(int* pCakeArray, int pCakeCount)
    {
        Init(pCakeArray, pCakeCount);
        nSearch = 0;
        Search(0);
    }

    void Output()
    {
        for(int i = 0; i < MaxSwap; i++)
        {
            cout<

你可能感兴趣的:(《编程之美》习题)