传说在公园1世纪的犹太战争中,犹太约瑟夫是公元一世纪著名的历史学家。在罗马人占领乔塔帕特后,39 个犹太人与约瑟夫及他的朋友躲到一个洞中,39个犹太人决定宁愿死也不要被敌人俘虏,于是决定了一个流传千古的自杀方式,41个人排成一个圆圈,由第1个人开始报数,每报到第3人该人就必须自杀,然后再由下一个人重新报数,直到所有人都自杀身亡为止。然而约瑟夫和他的朋友并不想遵从这个约定,约瑟夫要他的朋友先假装遵从,他将朋友与自己安排在第_个和第_个位置,于是逃过了这场死亡游戏,你知道安排在了第几个嘛?
针对以上问题,使用单向循环链表的方式求解。
代码如下:
<script type="text/javascript">
//节点类
function Node(elemnt) {
this.item = elemnt;
this.next = null;
}
//循环列表需要修改一下构造函数,和遍历时候的判断条件
//构造函数如下;希望从后向前遍历,又不想要建立双向链表,就使用循环链表。
function Llist() {
this.head = new Node("1");
this.head.next = this.head;
this.remove = remove;
this.insert = insert;
this.find = find;
this.display = display;
//..........
}
function find(number) {
var curr = this.head;
while (curr.item != number) {
curr = curr.next;
}
return curr;
}
function insert(element, newElement) {
var preNode = this.find(element);
var current = new Node(newElement);
current.next = preNode.next;
preNode.next = current;
}
function remove() {
var current = this.head;
console.log("remove");
var hh = 0;
//跳过两个,杀死一个
while (current.next.next != null && current.item != current.next.next.item) {
var temp = current.next.next;
current.next.next = temp.next;
current = temp.next;
temp.next = null;
}
return current;
}
function display(flag,current) {
var crr = this.head;
//
if (flag) {
while(crr.next.item!="1"){
console.log(crr.item);
crr = crr.next;
}
} else {//最后只剩两个直接输出
console.log(current.item);
console.log(current.next.item);
}
}
var Clist = new Llist();
//输入排序
for (var i = 1; i < 41; i++) {
Clist.insert(i.toString(), (i + 1).toString());
}
//先输出所有
Clist.display(1,null);
通过remove返回最后杀死后的结果其中一个节点
Clist.display(0,Clist.remove());
</script>
可以得到最后位置是16、31。