cpp生成1到n生成全排列的三种方法

要求:按字典序输出1到n的全排列
法一:next_permutation();

include

include

using namespace std;
int main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
int a[]={1,2,3,4,5,6,7,8};
do{
for(int i=0;i<8;i++)
{
cout<<a[i];
if(i!=7)cout<<" ";
}
cout<<endl;
}while(next_permutation(a,a+8));
return 0;
}
以一到八为例,使用Stl的algorithm库中的next_permutation()方法,自动生成下一个字典序的全排列,前提是先有一个全排列,所以使用do while循环,先输出最小字典序12345678,如果下一字典序为最大字典序,也就是降序,next_permutation()会返回false,反之返回true,所以循环条件即为next_permutation(),即可按字典序生成1到8的全排列
法二:栈

include

include

include

using namespace std;
struct State{
vector current;
vector rest;
};
int main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
stackst;
st.push({{},{1,2,3,4,5,6,7,8}});
while(!st.empty())
{
State s=st.top();
st.pop();
if(s.rest.empty())
{
for(int i=0;i<s.current.size();i++)
{
cout<<s.current[i];
if(i!=s.current.size()-1)
cout<<" ";

        }
        cout<<endl;
        continue;
    }
    
        
        for(int i=s.rest.size()-1;i>=0;i--)
        {
            vector<int>new_current=s.current;
            new_current.push_back(s.rest[i]);
            vector<int>new_rest;
        for(int j=0;j<s.rest.size();j++)
        {
            if(j!=i)
            {
                new_rest.push_back(s.rest[j]);
            }
        } 
            st.push({new_current,new_rest});
        }      
    
}

return 0;

}
利用栈先进后出的属性,通过栈保存当前已生成排列和剩余可用数字的状态。如果没有剩余可用数字,那就输出已生成的排列,如果有可用数字,说明排列还没生成完,那就从剩余可选数字中每次拿一个到已生成排列中,形成新的排列,同时更新剩余可用数字,
注意:由于先进后出的属性,想按字典序顺序生成,需要倒序选取,这样小的数字才能先出来
法三:队列

include

include

include

using namespace std;
struct State{
vector current;
vector rest;
};
int main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
queueq;
q.push({{},{1,2,3,4,5,6,7,8}});
while(!q.empty())
{
State s=q.front();
q.pop();
if(s.rest.empty())
{
for(int i=0;i<s.current.size();i++)
{
cout<<s.current[i];
if(i!=s.current.size()-1)
cout<<" ";

        }
        cout<<endl;
        continue;
    }
    
        
        for(int i=0;i<s.rest.size();i++)
        {
            vector<int>new_current=s.current;
            new_current.push_back(s.rest[i]);
            vector<int>new_rest;
        for(int j=0;j<s.rest.size();j++)
        {
            if(j!=i)
            {
                new_rest.push_back(s.rest[j]);
            }
        } 
            q.push({new_current,new_rest});
        }      
    
}
return 0;

}
与栈的方法基本一致,区别在于,队列有先进先出的属性,要想按字典序顺序输出,需要升序选取,从小到大。

posted @ 2025-11-04 21:16  lagranSun  阅读(30)  评论(0)    收藏  举报