全排列算法(字典序法、SJT Algorithm 、Heap's Algorithm)

时间:2022-09-20 16:04:46

一、字典序法

1) 从序列P的右端开始向左扫描,直至找到第一个比其右边数字小的数字全排列算法(字典序法、SJT Algorithm 、Heap's Algorithm),即全排列算法(字典序法、SJT Algorithm 、Heap's Algorithm)

2) 从全排列算法(字典序法、SJT Algorithm 、Heap's Algorithm)右边找出所有比全排列算法(字典序法、SJT Algorithm 、Heap's Algorithm)大的数中最小的数字全排列算法(字典序法、SJT Algorithm 、Heap's Algorithm),即全排列算法(字典序法、SJT Algorithm 、Heap's Algorithm)

3) 交换全排列算法(字典序法、SJT Algorithm 、Heap's Algorithm)全排列算法(字典序法、SJT Algorithm 、Heap's Algorithm)

4) 将全排列算法(字典序法、SJT Algorithm 、Heap's Algorithm)右边的序列翻转,即可得到字典序的下一个排列。

5) 重复上面的步骤,直至得到字典序最大的排列,即左边数字比右边的大的降序排列。

//字典序法
void dictionary(int length){
int * data = (int *)malloc(sizeof(int) * length);
int index;
for (index = 0; index < length; ++index)
data[index] = index + 1;
FILE * fp = fopen("dictionary.txt", "w");
print(fp, data, length);
while (nextPermutation(data, 0, length)){
print(fp, data, length);
}
fclose(fp);
free(data);
} void swap(int data[], int i, int j){//交换两个元素
char temp;
temp = data[i];
data[i] = data[j];
data[j] = temp;
} void reverse(int data[], int first, int last){//翻转序列
last--;
while (first < last){
swap(data, first++, last--);
}
} int nextPermutation(int data[], int first, int last){
int i, j;
i = last - 2;
while (i >= 0 && data[i] >= data[i+1])
--i;
if (i == -1){
reverse(data, first, last);
return 0;
}
j = last - 1;
while (data[j] <= data[i]){
--j;
}
swap(data, i, j);
reverse(data, i + 1, last);
return 1;
} void print(FILE * fp, int data[], int length){
int index;
for (index = 0; index < length; ++index){
fprintf(fp, "%d ", data[index]);
}
fprintf(fp, "\n");
}

二、SJT Algorithm

初始状态为全排列算法(字典序法、SJT Algorithm 、Heap's Algorithm)

1) 找到最大的可移动数m(当一个数指向一个比它小的数是,该数就是可移动数)

2) 交换m和m所指向的数

3) 改变所有比m大的数的方向

4) 重复上面的步骤,直至找不到可移动数

//邻位对换法
void exchange(int length){
Item * data = (Item *)malloc(sizeof(Item) * length);
int index, indexOfMax;
for (index = 0; index < length; ++index){
data[index].digit = index + 1;
data[index].direction = -1;
data[index].mobile = (index != 0) ? 1 : 0;
}
indexOfMax = length - 1;
FILE * fp = fopen("exchange.txt", "w");
exPrint(data, length, fp);
while (1== data[indexOfMax].mobile || existMobile(data, length)){
if (1== data[indexOfMax].mobile){
int direction = data[indexOfMax].direction;
exSwap(data, indexOfMax, indexOfMax+direction);
indexOfMax += direction;
if ((indexOfMax == 0 && direction == -1) || (indexOfMax == length-1 && direction == 1)){
toMobileorNot(data, length);
}
} else{
index = findMax(data, length);
if (index == -1)
break;
int direction = data[index].direction;
exSwap(data, index, index + direction);
index += direction;
changeDirection(data, length, index);
toMobileorNot(data, length);
}
exPrint(data, length, fp);
}
fclose(fp);
free(data);
} int existMobile(Item data[], int length){//判断是否存在可移动数
int index;
for (index = 0; index < length; ++index){
if (data[index].mobile == 1)
return 1;
}
return 0;
} int findMax(Item data[], int length){//找到最大的可移动数
int ans = -1;
for (int index = 0; index < length; ++index){
if (data[index].mobile == 1){
if (ans == -1)
ans = index;
else if (data[index].digit > data[ans].digit)
ans = index;
}
} return ans;
} void changeDirection(Item data[], int length, int index){//改变大于可移动数的数的方向
for (int i = 0; i < length; ++i){
if (data[i].digit > data[index].digit){
data[i].direction = -data[i].direction;
}
}
} void toMobileorNot(Item data[], int length){
if (data[0].direction == 1 && data[0].digit > data[1].digit)
data[0].mobile = 1;
else
data[0].mobile = 0; for (int i = 1; i < (length - 1); ++i){
int direction = data[i].direction;
if (data[i].digit > data[i+direction].digit)
data[i].mobile = 1;
else
data[i].mobile = 0;
} if (data[length-1].direction == -1 && data[length-1].digit > data[length-2].digit)
data[length-1].mobile = 1;
else
data[length-1].mobile = 0;
} void exPrint(Item data[], int length, FILE * fp){
for (int index = 0; index < length; ++index){
fprintf(fp, "%d ", data[index].digit);
}
fprintf(fp, "\n");
} void exSwap(Item data[], int i, int j){
Item tmp = data[i];
data[i] = data[j];
data[j] = tmp;
}

三、Heap's Algorithm

    procedure generate(n : integer, A : array of any):
if n = 1 then
output(A)
else
for i := 1; i ≤ n; i += 1 do
generate(n - 1, A)
if n is odd then
j ← 1
else
j ← i
swap(A[j], A[n])

以上算法描述摘自*

//Recursive implementation.
#include <stdio.h>
#include <stdlib.h>
#include <time.h> FILE * fp = NULL;
int len; int str2int(char str[]){
int i = 0;
int result = 0;
while (str[i] != '\0'){
result = result * 10 + str[i] - '0';
++i;
}
return result;
} void print(int data[]){
int i;
for (i = 0; i < len; ++i)
fprintf(fp, "%d ", data[i]);
fprintf(fp, "\n");
} void swap(int *x, int *y){
int tmp = *x;
*x = *y;
*y = tmp;
} void generate(int data[], int n){
int i;
if (1 == n)
print(data);
//return;
else{
for (i = 0; i < n; ++i){
generate(data, n-1);
if (n % 2 == 1){
swap(&data[1], &data[n-1]);
} else{
swap(&data[i], &data[n-1]);
}
}
}
} void heapAlgorithm(int n){
int * data = (int *)malloc(sizeof(int) * n);
int i;
for(i = 0; i < n; ++i)
data[i] = i + 1;
generate(data, n);
free(data);
}
int main(int argc, char **argv){
fp = fopen("heap.txt", "w");
len = (argc > 1) ? str2int(argv[1]) : 10;
clock_t time = clock();
heapAlgorithm(len);
time = clock() - time;
printf("Heap's Algorithm takes %d clocks(%f seconds).\n", time, ((float)time)/CLOCKS_PER_SEC);
return 0;
}

全排列算法(字典序法、SJT Algorithm 、Heap's Algorithm)的更多相关文章

  1. 两种常用的全排列算法&lpar;java&rpar;

    问题:给出一个字符串,输出所有可能的排列. 全排列有多种算法,此处仅介绍常用的两种:字典序法和递归法. 1.字典序法: 如何计算字符串的下一个排列了?来考虑"926520"这个字符 ...

  2. 不会全排列算法&lpar;Javascript实现&rpar;,我教你呀!

    今天我很郁闷,在实验室凑合睡了一晚,准备白天大干一场,结果一整天就只做出了一道算法题.看来还是经验不足呀,同志仍需努力呀. 算法题目要求是这样的: Return the number of total ...

  3. K条最短路径算法&lpar;KSP&comma; k-shortest pathes&rpar;:Yen&&num;39&semi;s Algorithm

    参考: K最短路径算法之Yen's Algorithm Yen's algorithm 基于网络流量的SDN最短路径转发应用 K条最短路径算法:Yen's Algorithm 算法背景 K 最短路径问 ...

  4. 全排列算法的JS实现

    问题描述:给定一个字符串,输出该字符串所有排列的可能.如输入“abc”,输出“abc,acb,bca,bac,cab,cba”. 虽然原理很简单,然而我还是折腾了好一会才实现这个算法……这里主要记录的 ...

  5. 【Java】-NO&period;13&period;Algorithm&period;1&period;Java Algorithm&period;1&period;001-【Java 常用算法手册 】-

    1.0.0 Summary Tittle:[Java]-NO.13.Algorithm.1.Java Algorithm.1.001-[Java 常用算法手册 ]- Style:Java Series ...

  6. &lbrack;Algorithm&rsqb; Heap data structure and heap sort algorithm

    Source, git Heap is a data structure that can fundamentally change the performance of fairly common ...

  7. PHP字符串全排列算法

    <?php /** * PHP字符串全排列算法 */ $results = []; $arr = []; function bfs($start) { global $arr; global $ ...

  8. 全排列算法--递归实现&lpar;Java&rpar;

    求一个n阶行列式,一个比较简单的方法就是使用全排列的方法,那么简述以下全排列算法的递归实现. 首先举一个简单的例子说明算法的原理,既然是递归,首先说明一下出口条件.以[1, 2]为例 首先展示一下主要 ...

  9. C程序数组算法 — 冒泡法排序【前冒 &vert;&vert; 后冒】

    第一种写法(前冒泡): /* C程序数组算法 - 冒泡法排序 * 此例子按照 大 -> 小 排序 * 原理:两两相比较,然后进行大小对调 * 比较次数: n^2 次 * 说明:冒泡排序是相对稳定 ...

随机推荐

  1. 在servlet中用spring &commat;Autowire注入

    今天在改版以前应用程序的时候,发现很多系统是直接用servlet做的.当初也用到了spring,所以自然想到也用spring的@autowire注入来引入service层.但发现如果直接用,有时候成功 ...

  2. Smali语法编程

    Smali背景: Smali,Baksmali分别是指安卓系统里的Java虚拟机(Dalvik)所使用的一种.dex格式文件的汇编器,反汇编器.其语法是一种宽松式的Jasmin/dedexer语法,而 ...

  3. python简明手册学习

    1.行末单独一个反斜杠表示字符串在下一行继续,而不是开始一个新的行. >>> "This is the first sentence.\ ... This is the s ...

  4. 阿里云里面的Linux 系统挂载数据盘

    转自:http://www.cnblogs.com/adjk/p/5112360.html 适用系统:非IO优化+SSD云盘Linux(Redhat , CentOS,Debian,Ubuntu)实例 ...

  5. 简化的nginx多进程模型demo

    //version 1:以下代码仅演示nginx多进程模型[test@vm c]$ cat mynginx.c#include <stdio.h> #include <string. ...

  6. 基本 XAML 语法指南

    我们介绍了 XAML 语法规则,以及用于描述 XAML 语法中存在的限制或选项的术语.当出现以下情况时你会发现本主题很有用:不熟悉 XAML 语言的使用,希望加强对术语或某些语法部分的理解,或者对 X ...

  7. Monad详解

    最近几年,函数式编程变得越来越流程,其代码简洁.副作用小.维护成本低等特点,使得许多其它的语言也开始支持函数式编程,比如Java 和 C#等.本文主要介绍一下函数式编程中的一个重要概念:Monad. ...

  8. es &lowbar;cat API

    1.集群健康 curl -X GET "10.0.38.111:1200/_cluster/health?pretty"

  9. react &plus;webpack 配置px2rem

    项目背景需要适配ipad 以及手机端,这时候当然要告别刀耕火种时代啦(自己算rem),因为已经有成熟的工具啦,即px2rem(https://www.npmjs.com/package/px2rem) ...

  10. STL基础--流

    流 介绍 // cout: 全局ostream对象,(typedef basic_ostream<char> ostream) // <<: ostream& ostr ...