只是一些比较简单的算法实现,记录下来以便以后查看
JohnsonTroter 排列生成算法
将第一个排列初始化, while 存在一个可移动元素k do, 求最大的移动元素k, 把k和它箭头指向的相邻元素互换, 调转所有大于k的元素的方向, 将新排列添加到列表。
#include<iostream>
using namespace std;
struct A
{
int num; //排列的数
int isleft; //是否在左边,左为-1, 右为1
};
int isexit(A* &data, const int& n)
{
for(int i=0;i<n;i++)
{
int index = i+data[i].isleft;
if(( (index>=0 && index<n) && data[index].num < data[i].num))
{
return i;
}
}
return -1;
}
int max(A* &data, const int &n, int i)
{
int m = i;
for(;i<n;i++)
{
int index = i+data[i].isleft;
if( (index>=0 && index<n ) && data[i].num>data[index].num)
{
if(data[m].num<data[i].num)
m = i;
}
}
return m;
}
void display(A* &data, const int &n)
{
for(int i=0;i<n;i++)
{
cout<<data[i].num<<" ";
}
cout<<endl;
}
void swap(A* &data, int &i, int j)
{
A temp;
temp = data[i];
data[i] = data[j];
data[j] = temp;
}
int main()
{
int n;
cin>>n;
A* data = new A[n];
for(int i=0;i<n;i++)
{
data[i].num = i+1;
data[i].isleft = -1;
}
display(data, n);
int index;
int sum = 1;
while((index=isexit(data, n))!=-1)
{
index = max(data, n, index);
for(int i=0;i<n;i++)
{
if(data[i].num>data[index].num)
data[i].isleft *= -1;
}
swap(data, index, index+data[index].isleft);
display(data, n);
}
cout<<sum;
}
以字典正序生成排列:
#include<iostream>
#include<algorithm>
using namespace std;
int computei(int* &data, const int &n)
{
for(int i=n-2;i>=0;i--)
{
if(data[i+1]>data[i])
return i;
}
return -1;
}
void swap(int* &data, int i, int j)
{
int temp = data[i];
data[i] = data[j];
data[j]= temp;
}
void display(int* &data, const int &n)
{
for(int i=0;i<n;i++)
cout<<data[i]<<" ";
cout<<endl;
}
int main()
{
int n;
cin>>n;
int* data = new int[n];
for(int i=0;i<n;i++)
data[i] = i+1;
display(data, n);
int index;
while( (index=computei(data, n) )!=-1)
{
int j = index+1;
for(int i=index+1;i<n;i++)
{
if(data[i]>data[index] && data[j]>data[i])
j = i;
}
swap(data, index, j);
sort(data+index+1,data+n);
display(data, n);
}
}
感谢阅读~