Javascript中的循环链接列表同胞游戏
我在O'Reilly的Javascript数据结构和算法中发现了这个问题“根据传说,一世纪的犹太历史学家弗拉维乌斯·约瑟夫大约 在战争期间与40名同胞一起被罗马士兵俘虏 犹太-罗马战争。犹太士兵决定他们宁愿自杀也不愿被杀害 俘虏并设计了他们的死亡计划。他们要围成一个圈并杀戮 每三名士兵中就有一名,直到他们全部死去。约瑟夫斯和另外一名决定 不想参与其中,并迅速计算出他们需要将自己放在哪里 所以他们将是最后的幸存者。写一个程序,允许你放置n 将所有人围成一个圈,并指定每一个mth人都将被杀害 应确定圆圈中最后两个人的人数。循环使用 链表来解决这个问题。” 这是我的解决方案Javascript中的循环链接列表同胞游戏,javascript,linked-list,circular-list,Javascript,Linked List,Circular List,我在O'Reilly的Javascript数据结构和算法中发现了这个问题“根据传说,一世纪的犹太历史学家弗拉维乌斯·约瑟夫大约 在战争期间与40名同胞一起被罗马士兵俘虏 犹太-罗马战争。犹太士兵决定他们宁愿自杀也不愿被杀害 俘虏并设计了他们的死亡计划。他们要围成一个圈并杀戮 每三名士兵中就有一名,直到他们全部死去。约瑟夫斯和另外一名决定 不想参与其中,并迅速计算出他们需要将自己放在哪里 所以他们将是最后的幸存者。写一个程序,允许你放置n 将所有人围成一个圈,并指定每一个mth人都将被杀害 应确定
function Node(element) {
this.element = element;
this.next = null;
}
function LList() {
this.head = new Node("head");
this.head.next = this.head;
this.find = find;
this.insert = insert;
this.display = display;
this.findPrevious = findPrevious;
this.remove = remove;
this.advance = advance;
this.count = count;
}
function remove(item) {
var prevNode = this.findPrevious(item);
if (!(prevNode.next == this.head)) {
prevNode.next = prevNode.next.next;
}
}
function findPrevious(item) {
var currNode = this.head;
while (!(currNode.next == this.head) &&
(currNode.next.element != item)) {
currNode = currNode.next;
}
return currNode;
}
function display() {
var currNode = this.head;
while (!(currNode.next == this.head)) {
print(currNode.next.element);
currNode = currNode.next;
}
}
function count() {
var currNode = this.head;
var count = 0;
while (!(currNode.next == this.head)) {
count++
currNode = currNode.next;
}
return count;
}
function find(item) {
var currNode = this.head;
while (currNode.element != item) {
currNode = currNode.next;
}
return currNode;
}
function insert(newElement, item) {
var newNode = new Node(newElement);
var current = this.find(item);
newNode.next = current.next;
current.next = newNode;
}
function advance(item, n) {
var currNode = this.find(item);
for (let i = n; i > 0; i--) {
currNode = currNode.next;
}
return currNode;
}
function survivor(number, position) {
//40 compatriots
//kill every third soldier. advance by 3
//last two survivors
//place n people in a circle
var compatroits = new LList();
var currNode = compatroits.head;
for (let i = 1; i <= number; i++) {
compatroits.insert(i, currNode.element);
currNode = currNode.next;
}
//kill every mth person in the circle
//start from head
var currItem = compatroits.head.element;
while (compatroits.count() > 2) {
//advance mth person
var killNode = compatroits.advance(currItem, position);
//set new start point to m.next node
currItem = killNode.next.element;
//remove mth person
compatroits.remove(killNode.element);
}
//determine the last two people in the circle
return compatroits.display();
}
功能节点(元素){
this.element=元素;
this.next=null;
}
函数{
this.head=新节点(“head”);
this.head.next=this.head;
this.find=find;
this.insert=插入;
this.display=显示;
this.findPrevious=findPrevious;
这个。移除=移除;
这个。前进=前进;
this.count=计数;
}
功能移除(项目){
var prevNode=this.findPrevious(项目);
if(!(prevNode.next==this.head)){
prevNode.next=prevNode.next.next;
}
}
功能findPrevious(项目){
var currNode=this.head;
while(!(currNode.next==this.head)&&
(currNode.next.element!=项目)){
currNode=currNode.next;
}
返回节点;
}
函数显示(){
var currNode=this.head;
而(!(currNode.next==this.head)){
打印(currNode.next.element);
currNode=currNode.next;
}
}
函数计数(){
var currNode=this.head;
var计数=0;
而(!(currNode.next==this.head)){
计数++
currNode=currNode.next;
}
返回计数;
}
函数查找(项){
var currNode=this.head;
while(currNode.element!=项目){
currNode=currNode.next;
}
返回节点;
}
函数插入(新元素,项){
var newNode=新节点(newElement);
var current=此项。查找(项目);
newNode.next=current.next;
current.next=newNode;
}
功能推进(项目,n){
var currNode=this.find(项目);
对于(设i=n;i>0;i--){
currNode=currNode.next;
}
返回节点;
}
功能幸存者(数量、位置){
//40名同胞
//每杀三名士兵,前进三步
//最后两名幸存者
//把n个人围成一个圈
var compatroits=new LList();
var currNode=compatroits.head;
for(设i=1;i=2){
//高级mth人员
var killNode=compatroits.advance(当前项目、位置);
//将新起点设置为m.next节点
currItem=killNode.next.element;
//移除第m个人
compatroits.remove(killNode.element);
}
//确定圈中的最后两个人
返回compatroits.display();
}
有谁能找到更有效的方法来解决这个问题吗?当然有更有效的方法——特别是如果你愿意制作双链接列表的话。这对我来说可能是个好问题。但实际上,实际产出存在一些问题。例如,当我运行
survivor(40,3)
时,它看起来像是一个41-40加上头部的列表。然后每四个人删除一次。谢谢马克的反馈。我认为它似乎删除了第四个人,因为每当删除一个节点时,它就会重新开始计数。因此,已删除的节点不算作一个,而是将删除节点后的下一个节点算作一个。是的,它确实创造了40个元素加上头部。我确实认为我可以做出调整,以消除这两个bug。我也会在codereview上讨论它。再次感谢您的反馈