全排序:从n个不同元素中任取m(m≤n)个元素,按照一定的顺序排列起来,叫做从n个不同元素中取出m个元素的一个排列。当m=n时所有的排列情况叫全排列
1,3,2
2,1,3
2,3,1
3,1,2
3,2,1
共3*2*1=6种
如1,2,3三个元素的全排列为:
1,2,31,3,2
2,1,3
2,3,1
3,1,2
3,2,1
共3*2*1=6种
公式:全排列数f(n)=n!(定义0!=1)
一 全排序递归实现(不去掉重复情况)
// AllRange.cpp : 定义控制台应用程序的入口点。
//全排序——递归
//全排序——不考虑重复情况
#include "stdafx.h"
#include <iostream>
using namespace std;
template<class T>
void AllRangle(T data[], int arrsize, int key = 0)
{
if (key == arrsize)
{
Sprint(data, arrsize);
}
for (int i = key; i < arrsize; i++)
{
swap(data[key], data[i]);
AllRangle(data, arrsize, key + 1);
swap(data[key], data[i]);
}
}
template<class T>
void Sprint(T data[], int n)
{
for (int i = 0; i < n; i++)
{
cout << data[i] << " ";
}
cout << endl;
}
int _tmain(int argc, _TCHAR* argv[])
{
int data[] = { 0, 1, 2, 3 };
int n = sizeof(data) / sizeof(int);
AllRangle(data, n);
Sprint(data, n);
return 0;
}
结果:
二 全排序递归实现(去掉重复情况)
//递归
//全排序——考虑重复情况
#include "stdafx.h"
#include <iostream>
using namespace std;
//在pszStr数组中,[nBegin,nEnd)中是否有数字与下标为nEnd的数字相等
template<class T>
bool IsSwap(T data[], int nBegin, int nEnd)
{
for (int i = nBegin; i < nEnd; i++)
if (data[i] == data[nEnd])
return false;
return true;
}
template<class T>
void AllRangle(T data[], int arrsize, int key = 0)
{
if (key == arrsize)
{
Sprint(data, arrsize);
}
for (int i = key; i < arrsize; i++)
{
if (IsSwap(data, key, i))
{
swap(data[key], data[i]);
AllRangle(data, arrsize, key + 1);
swap(data[key], data[i]);
}
}
}
template<class T>
void Sprint(T data[], int n)
{
for (int i = 0; i < n; i++)
{
cout << data[i] << " ";
}
cout << endl;
}
int _tmain(int argc, _TCHAR* argv[])
{
char data[] = { '2', '1', '2' };
int n = sizeof(data) / sizeof(char);
AllRangle(data, n);
//Sprint(data, n);
return 0;
}
三 全排序非递归实现(去掉重复情况)
思路:给出一个数求出它的下一个数一直重复这个过程
分析:对于一串数字(字符串)将它由组合成最小数一直到组合成最大的数即为整个全排序过程
实现过程:
(1)例如235864 下一个数字为 236458,也就是5864 -> 6458
(2)将数字235864由后往前扫描当data[i] < data[i+1]说明此事 i 这个位置上的数字需要被别的数字取代
(3)在864中找到一个最小大于5的数,由于864为降序data[i]>data[j](j = length - 1, j--)需要交换的数为6,交换data[i]与data[j]( swap(data[i], data[j]) )
(4)后3位854进行倒转458,结果是236458
(5)重复上述过程直到下一个数字不存在为止
实例代码
#include "stdafx.h"
#include <iostream>
using namespace std;
template<class T>
void Reverse(T data[], int low, int hight)
{
for (; low < hight; low++, hight--)
{
swap(data[low], data[hight]);
}
}
template<class T>
void AllRangle(T data[], int length)
{
if (length < 2)
return;
int i, j;
while (true)
{
Sprint(data, length);
for (i = length - 2; i >= 0; i--)
{
if (data[i] < data[i + 1])
break;
else if (i == 0)
return;
}
for (j = length - 1; j > i; j--)
{
if (data[j] > data[i])
break;
}
swap(data[i], data[j]);
Reverse(data, i + 1, length - 1);
}
}
template<class T>
void Sprint(T data[], int n)
{
for (int i = 0; i < n; i++)
{
cout << data[i] << " ";
}
cout << endl;
}
int main(int argc, char **argv)
{
int data[] = { 1, 2, 3 };
int length = sizeof(data) / sizeof(int);
//打印不小于data(123)的所有数
AllRangle(data, length);
return 0;
}
备注:若data不是升序需要对data进行升序排序
结果:
int data[] = { 1, 2, 3 }
int data[] = { 1, 2, 2 }