全排序(All Rangled)

来源:互联网 发布:vscode php注释插件 编辑:程序博客网 时间:2024/04/30 10:13
全排序:从n个不同元素中任取m(m≤n)个元素,按照一定的顺序排列起来,叫做从n个不同元素中取出m个元素的一个排列。当m=n时所有的排列情况叫全排列


如1,2,3三个元素的全排列为:

1,2,3
1,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 }










0 0
原创粉丝点击