排列的生成算法 换位算法实现

//采用换位法,n个元素的生产函数
//有一组测试数据
//  3
//  2 6 5
//

//测试数据无法通过啊,这是一个很GB的算法啊,居然有个前提条件n个元素的集合是{1,2,3..n},其实想想也算的过去,把元素存在数组里面,数组下标从1ton也是正常的

//稍微转换一下就可以了,我起初用上面的数据区测试才发现,结果不对!因为这个算法的前提条件就是from 1 to n

//算法详情参考组合数学《殷剑宏版》  15页

//我把n设置成了9,第一次看到程序跑的这么吃力啊,三十几万次的排列,哎,伤不起啊


#include<iostream>
using namespace std;

#define LEFT 0
#define RIGHT 1
#define MAX 10000



struct Elem
{
    Elem(){
        value=MAX*100;//这个值要很大,否则在边缘比较的时候就会出现错误,错误指示边缘数据是活动的
        direction=LEFT;
    }
    int value;//数值
    int direction;//方向
};

int num;
Elem collection[MAX];

int IsActive(int index)//返回活动的下标索引
{
    if(index==1&&collection[index].direction==LEFT)
        return 0;
    if(collection[index].direction==LEFT)
    {
        if(collection[index-1].value<collection[index].value)
            return index;
    }
    else if(collection[index].direction==RIGHT)
    {
        if(collection[index+1].value<collection[index].value)
            return index;
    }
    return 0;
}

bool ChangeElem(int index)//传进的是将要交换的元素的下标
{
  if(collection[index].direction==LEFT)//向左传递那么他们的值就和前面一个数据交换,否则和右边的一个数据交换
  {
   int tempValue=collection[index-1].value;//交换两者的值和方向
   int tempDirection =collection[index-1].direction;

   collection[index-1].value=collection[index].value;
   collection[index-1].direction=collection[index].direction;

   collection[index].value =tempValue ;
   collection[index].direction =tempDirection;

   return true;
  }
  if(collection[index].direction==RIGHT)
  {
   int tempValue=collection[index+1].value;
   int tempDirection =collection[index+1].direction;

   collection[index+1].value=collection[index].value;
   collection[index+1].direction=collection[index].direction;

   collection[index].value =tempValue ;
   collection[index].direction =tempDirection;

   return true;
  }
  return false;
}

bool ChangeDirect(int m)//当某个值大于当前最大的活动数据的时候,改变改数据的方向
{
    bool flag=false;
    for(int i=1;i<=num;i++)
    {
        if(collection[i].value>collection[m].value)
        {
            flag=true;
            if(collection[i].direction==LEFT)
            {
                collection[i].direction=RIGHT;
            }
            else if(collection[i].direction==RIGHT)
            {
                collection[i].direction=LEFT;
            }
        }
    }
    return flag;
}

int main()
{
    cout<<"请问你要输入多少个元素啊?"<<endl;
    cin>>num;
    cout<<"请连续输入"<<num<<"个元素"<<endl;
    for(int i=1;i<=num;i++)
        cin>>collection[i].value;
    int no=1;
    //找出最大的M
    cout<<no<<": ";
    for(int j=1;j<=num;j++)//输出第一组元素
    {
        cout<<collection[j].value<<" ";
    }
    cout<<endl;
    while(1)//如果有活动的数据则一直执行while循环,若是IsActive返回0,那么表明当前没有活动的元素了,那么就结束循环
    {
    int maxM=0;
    int maxIndex=0;
    for(int j=1;j<=num;j++)
    {
        int temp =IsActive(j);
        /*if(temp)
        {
         cout<<temp<<endl;
        }*/
        if(!temp)//如果不是活动的,返回0,这时候无需要再另行处理数据
            continue;
        if(collection[temp].value>maxM) //如果当前的值大于最大活动整数maxM,那么就将最大值
        {
            maxM = collection[temp].value;
            maxIndex = temp;
        }
    }

    if(maxIndex==0)
    {
        break;
    }

    ChangeDirect(maxIndex);

    if(!ChangeElem(maxIndex))
    {
        cout<<"交换异常!"<<endl;
    }

    cout<<++no<<": ";
    for(int s= 1;s<=num;s++)
    {
    cout<<collection[s].value<<":"<<collection[s].direction<<" ";
    }

    cout<<endl;
    }

    return 0;
}

运行结果如下:



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值