一、字典序法
1) 从序列P的右端开始向左扫描,直至找到第一个比其右边数字小的数字,即。
2) 从右边找出所有比大的数中最小的数字,即。
3) 交换与。
4) 将右边的序列翻转,即可得到字典序的下一个排列。
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
初始状态为。
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)的更多相关文章
-
两种常用的全排列算法(java)
问题:给出一个字符串,输出所有可能的排列. 全排列有多种算法,此处仅介绍常用的两种:字典序法和递归法. 1.字典序法: 如何计算字符串的下一个排列了?来考虑"926520"这个字符 ...
-
不会全排列算法(Javascript实现),我教你呀!
今天我很郁闷,在实验室凑合睡了一晚,准备白天大干一场,结果一整天就只做出了一道算法题.看来还是经验不足呀,同志仍需努力呀. 算法题目要求是这样的: Return the number of total ...
-
K条最短路径算法(KSP, k-shortest pathes):Yen&#39;s Algorithm
参考: K最短路径算法之Yen's Algorithm Yen's algorithm 基于网络流量的SDN最短路径转发应用 K条最短路径算法:Yen's Algorithm 算法背景 K 最短路径问 ...
-
全排列算法的JS实现
问题描述:给定一个字符串,输出该字符串所有排列的可能.如输入“abc”,输出“abc,acb,bca,bac,cab,cba”. 虽然原理很简单,然而我还是折腾了好一会才实现这个算法……这里主要记录的 ...
-
【Java】-NO.13.Algorithm.1.Java Algorithm.1.001-【Java 常用算法手册 】-
1.0.0 Summary Tittle:[Java]-NO.13.Algorithm.1.Java Algorithm.1.001-[Java 常用算法手册 ]- Style:Java Series ...
-
[Algorithm] Heap data structure and heap sort algorithm
Source, git Heap is a data structure that can fundamentally change the performance of fairly common ...
-
PHP字符串全排列算法
<?php /** * PHP字符串全排列算法 */ $results = []; $arr = []; function bfs($start) { global $arr; global $ ...
-
全排列算法--递归实现(Java)
求一个n阶行列式,一个比较简单的方法就是使用全排列的方法,那么简述以下全排列算法的递归实现. 首先举一个简单的例子说明算法的原理,既然是递归,首先说明一下出口条件.以[1, 2]为例 首先展示一下主要 ...
-
C程序数组算法 — 冒泡法排序【前冒 || 后冒】
第一种写法(前冒泡): /* C程序数组算法 - 冒泡法排序 * 此例子按照 大 -> 小 排序 * 原理:两两相比较,然后进行大小对调 * 比较次数: n^2 次 * 说明:冒泡排序是相对稳定 ...
随机推荐
-
在servlet中用spring @Autowire注入
今天在改版以前应用程序的时候,发现很多系统是直接用servlet做的.当初也用到了spring,所以自然想到也用spring的@autowire注入来引入service层.但发现如果直接用,有时候成功 ...
-
Smali语法编程
Smali背景: Smali,Baksmali分别是指安卓系统里的Java虚拟机(Dalvik)所使用的一种.dex格式文件的汇编器,反汇编器.其语法是一种宽松式的Jasmin/dedexer语法,而 ...
-
python简明手册学习
1.行末单独一个反斜杠表示字符串在下一行继续,而不是开始一个新的行. >>> "This is the first sentence.\ ... This is the s ...
-
阿里云里面的Linux 系统挂载数据盘
转自:http://www.cnblogs.com/adjk/p/5112360.html 适用系统:非IO优化+SSD云盘Linux(Redhat , CentOS,Debian,Ubuntu)实例 ...
-
简化的nginx多进程模型demo
//version 1:以下代码仅演示nginx多进程模型[test@vm c]$ cat mynginx.c#include <stdio.h> #include <string. ...
-
基本 XAML 语法指南
我们介绍了 XAML 语法规则,以及用于描述 XAML 语法中存在的限制或选项的术语.当出现以下情况时你会发现本主题很有用:不熟悉 XAML 语言的使用,希望加强对术语或某些语法部分的理解,或者对 X ...
-
Monad详解
最近几年,函数式编程变得越来越流程,其代码简洁.副作用小.维护成本低等特点,使得许多其它的语言也开始支持函数式编程,比如Java 和 C#等.本文主要介绍一下函数式编程中的一个重要概念:Monad. ...
-
es _cat API
1.集群健康 curl -X GET "10.0.38.111:1200/_cluster/health?pretty"
-
react +webpack 配置px2rem
项目背景需要适配ipad 以及手机端,这时候当然要告别刀耕火种时代啦(自己算rem),因为已经有成熟的工具啦,即px2rem(https://www.npmjs.com/package/px2rem) ...
-
STL基础--流
流 介绍 // cout: 全局ostream对象,(typedef basic_ostream<char> ostream) // <<: ostream& ostr ...