约瑟夫(Joseph)问题的一种描述是:编号为1,2,..., n的n个人按顺时针方向围坐一圈,
每人持有一个密码(正整数)。一开始选任一个正整数作为报数上限值m,从第一个人开始按顺时针方向自1开始顺序报数,报到m时停止报数。报m的人出列,将它的密码作为新的m值。试设计一个程序求出出列顺序。
测试数据:m的初值为20;n=7,7个人的密码依次为:3,1,7,2,4,8,4(正确的出列顺序应为6,1,4,7,2,3,5)
下面介绍3种使用js实现的算法:
1、普通的:
1 /*普通的算法*/
2 var arr = [{ 1: 3 }, { 2: 1 }, { 3: 7 }, { 4: 2 }, { 5: 4 }, { 6: 8 }, { 7: 4 }];
3 var m = 20, n = 0;
4 var arrlen = arr.length;
5 var b = 0;
6 for (var i = 0; i < arrlen; i++) {
7 var index = (n + m-1) % arr.length;
8 var o = arr[index];
9 for (var nn in o) {
10 m = o[nn];
11 console.log(nn);
12 }
13 b = index;
14 arr.splice(index, 1);
15 n = index % arr.length;
16 }
3 var m = 20, n = 0;
4 var arrlen = arr.length;
5 var b = 0;
6 for (var i = 0; i < arrlen; i++) {
7 var index = (n + m-1) % arr.length;
8 var o = arr[index];
9 for (var nn in o) {
10 m = o[nn];
11 console.log(nn);
12 }
13 b = index;
14 arr.splice(index, 1);
15 n = index % arr.length;
16 }
2、使用双向链表
1 /*双向链表*/
2 var Obj = function (index, value, next, prev) {
3 this.index = index;
4 this.value = value;
5 this.next = next;
6 this.prev = prev;
7 }
8 var arr = [3, 1, 7, 2, 4, 8, 4];
9 var arrlen = arr.length;
10 var m = 20, n;
11 for (var i = 0; i < arrlen; i++) {
12 arr[i] = new Obj(i + 1, arr[i]);
13 }
14 for (var i = 0; i < arrlen; i++) {
15 if (i >= arrlen - 1) {
16 arr[i].next = arr[0];
17 } else {
18 arr[i].next = arr[i + 1];
19 }
20 if (i == 0) {
21 arr[i].prev = arr[arrlen - 1];
22 } else {
23 arr[i].prev = arr[i - 1];
24 }
25 }
26 for (var i = 0; i < arrlen; i++) {
27 for (var j = 0; j < m - 1; j++) {
28 n = n ? n : arr[0];
29 n = n.next;
30 }
31 m = n.value;
32 console.log(n.index);
33 n.next.prev = n.prev;
34 n.prev.next = n.next;
35 n = n.next;
36 }
3 this.index = index;
4 this.value = value;
5 this.next = next;
6 this.prev = prev;
7 }
8 var arr = [3, 1, 7, 2, 4, 8, 4];
9 var arrlen = arr.length;
10 var m = 20, n;
11 for (var i = 0; i < arrlen; i++) {
12 arr[i] = new Obj(i + 1, arr[i]);
13 }
14 for (var i = 0; i < arrlen; i++) {
15 if (i >= arrlen - 1) {
16 arr[i].next = arr[0];
17 } else {
18 arr[i].next = arr[i + 1];
19 }
20 if (i == 0) {
21 arr[i].prev = arr[arrlen - 1];
22 } else {
23 arr[i].prev = arr[i - 1];
24 }
25 }
26 for (var i = 0; i < arrlen; i++) {
27 for (var j = 0; j < m - 1; j++) {
28 n = n ? n : arr[0];
29 n = n.next;
30 }
31 m = n.value;
32 console.log(n.index);
33 n.next.prev = n.prev;
34 n.prev.next = n.next;
35 n = n.next;
36 }
3、使用单向链表
1 /*单向链表*/
2 var Obj = function (index, value, next) {
3 this.index = index;
4 this.value = value;
5 this.next = next;
6 }
7 var arr = [3, 1, 7, 2, 4, 8, 4];
8 var arrlen = arr.length;
9 var m = 20, n;
10 for (var i = 0; i < arrlen; i++) {
11 arr[i] = new Obj(i + 1, arr[i]);
12 }
13 for (var i = 0; i < arrlen; i++) {
14 if (i >= arr.length - 1) {
15 arr[i].next = arr[0];
16 } else {
17 arr[i].next = arr[i + 1];
18 }
19 }
20 for (var i = 0; i < arrlen; i++) {
21 for (var j = 0; j < m - 1; j++) {
22 n = n ? n : arr[0];
23 n = n.next;
24 }
25 m = n.value;
26 console.log(n.index);
27 for (var j = 0; j < arr.length; j++) {
28 if (arr[j] == n) {
29 if (j == 0) {
30 arr[arr.length - 1].next = n.next;
31 } else {
32 arr[j - 1].next = n.next;
33 }
34 n = n.next;
35 arr.splice(j,1)
36 break;
37 }
38 }
39 }
3 this.index = index;
4 this.value = value;
5 this.next = next;
6 }
7 var arr = [3, 1, 7, 2, 4, 8, 4];
8 var arrlen = arr.length;
9 var m = 20, n;
10 for (var i = 0; i < arrlen; i++) {
11 arr[i] = new Obj(i + 1, arr[i]);
12 }
13 for (var i = 0; i < arrlen; i++) {
14 if (i >= arr.length - 1) {
15 arr[i].next = arr[0];
16 } else {
17 arr[i].next = arr[i + 1];
18 }
19 }
20 for (var i = 0; i < arrlen; i++) {
21 for (var j = 0; j < m - 1; j++) {
22 n = n ? n : arr[0];
23 n = n.next;
24 }
25 m = n.value;
26 console.log(n.index);
27 for (var j = 0; j < arr.length; j++) {
28 if (arr[j] == n) {
29 if (j == 0) {
30 arr[arr.length - 1].next = n.next;
31 } else {
32 arr[j - 1].next = n.next;
33 }
34 n = n.next;
35 arr.splice(j,1)
36 break;
37 }
38 }
39 }