视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
JavaScript几种非递归全排列算法代码实例详解
2020-11-27 20:15:21 责编:小采
文档


回溯(非递归)

<html xmlns="http://www.w3.org/1999/xhtml"> 
<head> 
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 
 <title>Full Permutation(Non-recursive Backtrack) - Mengliao Software</title> 
</head> 
<body> 
<p> 
Full Permutation(Non-recursive Backtrack)<br /> 
Mengliao Software Studio - Bosun Network Co., Ltd.<br /> 
2012.03.29</p> 
<script type="text/javascript"> 
/* 
全排列(非递归回溯)算法 
1、建立位置数组,即对位置进行排列,排列成功后转换为元素的排列; 
2、第n个位置搜索方式与八皇后问题类似。 
*/ 
var count = 0; 
function show(arr) { 
 document.write("P<sub>" + ++count + "</sub>: " + arr + "<br />"); 
} 
function seek(index, n) { 
 var flag = false, m = n; //flag为找到位置排列的标志,m保存正在搜索哪个位置 
 do { 
 index[n]++; 
 if (index[n] == index.length) //已无位置可用 
 index[n--] = -1; //重置当前位置,回退到上一个位置 
 else if (!(function () { 
 for (var i = 0; i < n; i++) 
 if (index[i] == index[n]) return true; 
 return false; 
 })()) //该位置未被选择 
 if (m == n) //当前位置搜索完成 
 flag = true; 
 else 
 n++; 
 } while (!flag && n >= 0) 
 return flag; 
} 
function perm(arr) { 
 var index = new Array(arr.length); 
 for (var i = 0; i < index.length; i++) 
 index[i] = -1; 
 for (i = 0; i < index.length - 1; i++) 
 seek(index, i); 
 while (seek(index, index.length - 1)) { 
 var temp = []; 
 for (i = 0; i < index.length; i++) 
 temp.push(arr[index[i]]); 
 show(temp); 
 } 
} 
perm(["e1", "e2", "e3", "e4"]); 
</script> 
</body> 
</html>

排序(非递归)

<html xmlns="http://www.w3.org/1999/xhtml"> 
<head> 
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 
 <title>Full Permutation(Non-recursive Sort) - Mengliao Software</title> 
</head> 
<body> 
<p> 
Full Permutation(Non-recursive Sort)<br /> 
Mengliao Software Studio - Bosun Network Co., Ltd.<br /> 
2012.03.30</p> 
<script type="text/javascript"> 
/* 
全排列(非递归求顺序)算法 
1、建立位置数组,即对位置进行排列,排列成功后转换为元素的排列; 
2、按如下算法求全排列: 
设P是1~n(位置编号)的一个全排列:p = p1,p2...pn = p1,p2...pj-1,pj,pj+1...pk-1,pk,pk+1...pn 
(1)从排列的尾部开始,找出第一个比右边位置编号小的索引j(j从首部开始计算),即j = max{i | pi < pi+1} 
(2)在pj的右边的位置编号中,找出所有比pj大的位置编号中最小的位置编号的索引k,即 k = max{i | pi > pj} 
 pj右边的位置编号是从右至左递增的,因此k是所有大于pj的位置编号中索引最大的 
(3)交换pj与pk 
(4)再将pj+1...pk-1,pk,pk+1...pn翻转得到排列p' = p1,p2...pj-1,pj,pn...pk+1,pk,pk-1...pj+1 
(5)p'便是排列p的下一个排列 

例如: 
24310是位置编号0~4的一个排列,求它下一个排列的步骤如下: 
(1)从右至左找出排列中第一个比右边数字小的数字2; 
(2)在该数字后的数字中找出比2大的数中最小的一个3; 
(3)将2与3交换得到34210; 
(4)将原来2(当前3)后面的所有数字翻转,即翻转4210,得30124; 
(5)求得24310的下一个排列为30124。 
*/ 
var count = 0; 
function show(arr) { 
 document.write("P<sub>" + ++count + "</sub>: " + arr + "<br />"); 
} 
function swap(arr, i, j) { 
 var t = arr[i]; 
 arr[i] = arr[j]; 
 arr[j] = t; 

} 
function sort(index) { 
 for (var j = index.length - 2; j >= 0 && index[j] > index[j + 1]; j--) 
 ; //本循环从位置数组的末尾开始,找到第一个左边小于右边的位置,即j 
 if (j < 0) return false; //已完成全部排列 
 for (var k = index.length - 1; index[k] < index[j]; k--) 
 ; //本循环从位置数组的末尾开始,找到比j位置大的位置中最小的,即k 
 swap(index, j, k); 
 for (j = j + 1, k = index.length - 1; j < k; j++, k--) 
 swap(index, j, k); //本循环翻转j+1到末尾的所有位置 
 return true; 
} 
function perm(arr) { 
 var index = new Array(arr.length); 
 for (var i = 0; i < index.length; i++) 
 index[i] = i; 
 do { 
 var temp = []; 
 for (i = 0; i < index.length; i++) 
 temp.push(arr[index[i]]); 
 show(temp); 
 } while (sort(index)); 
} 
perm(["e1", "e2", "e3", "e4"]); 
</script> 
</body> 
</html>

求模(非递归)

<html xmlns="http://www.w3.org/1999/xhtml"> 
<head> 
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 
 <title>Full Permutation(Non-recursive Modulo) - Mengliao Software</title> 
</head> 
<body> 
<p>Full Permutation(Non-recursive Modulo)<br /> 
Mengliao Software Studio - Bosun Network Co., Ltd.<br /> 
2012.03.29</p> 
<script type="text/javascript"> 
/* 
全排列(非递归求模)算法 
1、初始化存放全排列结果的数组result,与原数组的元素个数相等; 
2、计算n个元素全排列的总数,即n!; 
3、从>=0的任意整数开始循环n!次,每次累加1,记为index; 
4、取第1个元素arr[0],求1进制的表达最低位,即求index模1的值w,将第1个元素(arr[0])插入result的w位置,并将index迭代为index\1; 
5、取第2个元素arr[1],求2进制的表达最低位,即求index模2的值w,将第2个元素(arr[1])插入result的w位置,并将index迭代为index\2; 
6、取第3个元素arr[2],求3进制的表达最低位,即求index模3的值w,将第3个元素(arr[2])插入result的w位置,并将index迭代为index\3; 
7、…… 
8、直到取最后一个元素arr[arr.length-1],此时求得一个排列; 
9、当index循环完成,便求得所有排列。 
例: 
求4个元素["a", "b", "c", "d"]的全排列, 共循环4!=24次,可从任意>=0的整数index开始循环,每次累加1,直到循环完index+23后结束; 
假设index=13(或13+24,13+2*24,13+3*24…),因为共4个元素,故迭代4次,则得到的这一个排列的过程为: 
第1次迭代,13/1,商=13,余数=0,故第1个元素插入第0个位置(即下标为0),得["a"]; 
第2次迭代,13/2, 商=6,余数=1,故第2个元素插入第1个位置(即下标为1),得["a", "b"]; 
第3次迭代,6/3, 商=2,余数=0,故第3个元素插入第0个位置(即下标为0),得["c", "a", "b"]; 
第4次迭代,2/4,商=0,余数=2, 故第4个元素插入第2个位置(即下标为2),得["c", "a", "d", "b"]; 
*/ 
var count = 0; 
function show(arr) { 
 document.write("P<sub>" + ++count + "</sub>: " + arr + "<br />"); 
} 
function perm(arr) { 
 var result = new Array(arr.length); 
 var fac = 1; 
 for (var i = 2; i <= arr.length; i++) 
 fac *= i; 
 for (index = 0; index < fac; index++) { 
 var t = index; 
 for (i = 1; i <= arr.length; i++) { 
 var w = t % i; 
 for (j = i - 1; j > w; j--) 
 result[j] = result[j - 1]; 
 result[w] = arr[i - 1]; 
 t = Math.floor(t / i); 
 } 
 show(result); 
 } 
} 
perm(["e1", "e2", "e3", "e4"]); 
</script> 
</body> 
</html>

下载本文
显示全文
专题