思路和步骤:

  1. 将数字赋予方向属性

  2. 理解什么叫可移动方向(后面在图片1中说明)

  3. 判断是否存在可移动元素
    bool judge_move(init* n_n, int n);

  4. 定义一个全局int k——>用来找出可移动元素中的最大值

  5. 定义一个全局int loc——>用来记录最大值当前所在的结构体数组中的位置

  6. 将loc所在的结构体整个和loc所在结构体指向的方向,邻接的结构体交换

  7. 调转所有大于最大值k的结构体的方向

  8. 输出显示

  9. 重复第3步,直到跳出循环

过程展示
图片描述
结果展示

clipboard.png

//生成全排列 johnson trotter 

#include <iostream>
using namespace std;

struct init
{
    int num;//数字
    int dir;//方向
};

//用来记录可移动值的最大值;
int k;
int loc = -1;//记录位置

bool judge_move(init* n_n, int n);
void johnson_trotter(int n);

int main()
{
    int n;//需要生成全排列的值
    cout << "输入需要进行全排列的值:    ";
    while (cin >> n, n != EOF)
    {
        cout << "可移动元素最大值    " << "排列    " << "方向(1左0右)" << endl;
        johnson_trotter(n);
        cout << "输入需要进行全排列的值:    ";
    }
    return 0;
}

void johnson_trotter(int n)
{
    //将 1...n 初始化
    init n_n[100];
    for (int i = 0; i < n; i++)
    {
        n_n[i].num = i + 1;
        n_n[i].dir = 1;//1 左   2 右
    }
    init temp;
    //直到 全部都不能 移动 结束
    //k  最大可移动值
    while (judge_move(n_n, n))
    {
        //最大值
        cout << "    " << k << "               ";

        //输出数值
        for (int i = 0; i < n; i++)
        {
            cout << n_n[i].num;
        }
        cout << "    ";

        //输出方向

        for (int i = 0; i < n; i++)
        {
            cout << n_n[i].dir;
        }
        cout << endl;

        //把k 和 它箭头 所指的值 互换
        //向左
        if (n_n[loc].dir == 1)
        {
            temp = n_n[loc];
            n_n[loc] = n_n[loc - 1];
            n_n[loc - 1] = temp;
        }
        //向右
        else if (n_n[loc].dir != 1)
        {
            temp = n_n[loc];
            n_n[loc] = n_n[loc + 1];
            n_n[loc + 1] = temp;
        }
        //调转所有 > k 值的方向
        for (int j = 0; j < n; j++)
        {
            if (n_n[j].num > k)
            {
                //左
                if (n_n[j].dir == 1)
                    n_n[j].dir = 0;
                else //右
                    n_n[j].dir = 1;
            }
        }
    }
    //最后一组没有可移动元素
    //最大值
    cout << "    无              ";

    //输出数值
    for (int i = 0; i < n; i++)
    {
        cout << n_n[i].num;
    }
    cout << "    ";

    //输出方向

    for (int i = 0; i < n; i++)
    {
        cout << n_n[i].dir;
    }
    cout << endl;
}

//判断是否存在 可以移动元素
bool judge_move(init* n_n, int n)
{
    k = -2147483647;
    bool judge = false;
    for (int i = 0; i < n; i++)
    {
        if (i == 0)
        {
            if (n_n[i].dir != 1 && n > 1)//首元素  向右
            {
                //大于 右邻接元素
                if (n_n[i].num > n_n[i + 1].num)
                {
                    if (n_n[i].num > k)
                    {
                        k = n_n[i].num;
                        loc = i;
                    }
                    judge = true;
                }
            }
        }
        else if (i == n - 1)
        {
            if (n_n[i].dir == 1 && n > 1)//最后一个元素 向左
            {
                //大于 左邻接元素
                if (n_n[i].num > n_n[i - 1].num)
                {
                    if (n_n[i].num > k)
                    {
                        k = n_n[i].num;
                        loc = i;
                    }
                    judge = true;
                }
            }
        }
        //向左
        else if (n_n[i].dir == 1 && n > 1)
        {
            if (n_n[i].num > n_n[i - 1].num)
            {
                if (n_n[i].num > k)
                {
                    k = n_n[i].num;
                    loc = i;
                }
                judge = true;
            }
        }
        //向右
        else if (n_n[i].dir != 1 && n > 1)
        {
            if (n_n[i].num > n_n[i + 1].num)
            {
                if (n_n[i].num > k)
                {
                    k = n_n[i].num;
                    loc = i;
                }
                judge = true;
            }
        }
    }
    return judge;
}

Light
11 声望0 粉丝

下一篇 »
合并算法