//采用换位法,n个元素的生产函数
//有一组测试数据
// 3
// 2 6 5
//
运行结果如下:
//有一组测试数据
// 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;
}
运行结果如下: