javascript循环链表之约瑟夫环的实现方法


Posted in Javascript onJanuary 16, 2017

前言

传说在公元1 世纪的犹太战争中,犹太历史学家弗拉维奥·约瑟夫斯和他的40 个同胞被罗马士兵包围。犹太士兵决定宁可自杀也不做俘虏,于是商量出了一个自杀方案。他们围成一个圈,从一个人开始,数到第三个人时将第三个人杀死,然后再数,直到杀光所有人。约瑟夫和另外一个人决定不参加这个疯狂的游戏,他们快速地计算出了两个位置,站在那里得以幸存。写一段程序将n 个人围成一圈,并且第m个人会被杀掉,计算一圈人中哪两个人最后会存活。使用循环链表解决该问题。

看到这个问题首先想到的是要用到循环链表,还有就是要计算链表中有多少个元素,这两点很重要。再有就是找到当前节点和在链表中向前移动m个节点。下面一一分析:循环链表很容易实现,就是初始化的时候使链表的头节点的下一个指向它自己,这样初始化一个空节点,注意链表的头不是节点。写法如下:this.head.next = this.head;计算链表中有多少个元素也很简单,只需要找到头节点,然后往下走直到再次回到头结点

代码如下:

var node = this.head;
var i = 0;
while (!(node.next.element == "head")){
 node = node.next;
 i++;
}
return i;

在初始化链表的时候我们定义一个当前节点,将它赋值为头节点this.currentNode = this.head; ,这样在移动节点的时候就可以用它指向下一个节点。向前移动节点的时候有个地方需要注意,如果当前移动到头节点上需要再向前移动一个节点this.currentNode.next.next

代码如下:

while (n>0){
 if(this.currentNode.next.element == "head"){
 this.currentNode = this.currentNode.next.next;
 }else{
 this.currentNode = this.currentNode.next;
 } 
 n--;
}

代码实现

/**
 * 使用循环链表实现解决约瑟夫环问题
 * */

//链表节点
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.findPrevious = findPrevious;
 this.remove = remove;
 this.currentNode = this.head;
 //从链表当前节点向前移动n个节点
 this.advance = advance; 
 //当前链表中有多少个元素
 this.count = count;
 this.display = display;
}

//查找节点
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 findPrevious(item){
 var currNode = this.head;
 while (!(currNode.next == null) && (currNode.next.element != item)){
 currNode = currNode.next;
 }
 return currNode;
}

//移除当前节点
function remove(item){
 var prevNode = this.findPrevious(item);
 if(!(prevNode.next == null)){
 prevNode.next = prevNode.next.next;
 }
}

//向前移动n个节点
function advance(n){
 while (n>0){
 if(this.currentNode.next.element == "head"){
  this.currentNode = this.currentNode.next.next;
 }else{
  this.currentNode = this.currentNode.next;
 } 
 n--;
 }
}

//当前链表中有多少个元素
function count(){
 var node = this.head;
 var i = 0;
 while (!(node.next.element == "head")){
 node = node.next;
 i++;
 }
 return i;
}

//输出所有节点
function display(){
 var currNode = this.head;
 while (!(currNode.next == null) && !(currNode.next.element == "head")){
 document.write(currNode.next.element + " ");
 currNode = currNode.next;
 }
}

var person = new LList();
person.insert('1','head');
person.insert('2', '1');
person.insert('3', '2');
person.insert('4' , '3');
person.insert('5' , '4');
person.insert('6' , '5');
person.insert('7' , '6');
person.insert('8' , '7');
person.insert('9' , '8');
person.insert('10' , '9');


person.display();
document.write('<br>');


var n = 3;
while (person.count() > 2){
 person.advance(n);
 person.remove(person.currentNode.element);
 person.display();
 document.write('<br>');
}

这里我们假设有10个人,每次数到第三个人的时候这个人自杀,最后输出的结果如下:

最后结果是约瑟夫和他的同伴一个站在队伍的第4个,一个站在队伍的第10个,最后只剩下他们两个人。不知道历史上有没有这件事,如果真的有这件事,在这么短的时间内解决这个问题,约瑟夫真他么是个天才,不知道当时他有没有用指针来解决这个问题,还是用普通的数组递归解决。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流。

Javascript 相关文章推荐
枚举JavaScript对象的函数
Dec 22 Javascript
extjs中grid中嵌入动态combobox的应用
Jan 01 Javascript
javascript模拟的Ping效果代码 (Web Ping)
Mar 13 Javascript
JavaScript在多浏览器下for循环的使用方法
Nov 07 Javascript
排序算法的javascript实现与讲解(99js手记)
Sep 28 Javascript
js判断是否按下了Shift键的方法
Jan 27 Javascript
javascript中undefined与null的区别
Aug 16 Javascript
基于jquery实现页面滚动到底自动加载数据的功能
Dec 19 Javascript
使用jQuery给input标签设置默认值
Jun 20 Javascript
详解数组Array.sort()排序的方法
May 09 Javascript
JS FormData上传文件的设置方法
Jul 05 Javascript
JavaScript 闭包的使用场景
Sep 17 Javascript
函数四种调用模式以及其中的this指向
Jan 16 #Javascript
js实现导航栏中英文切换效果
Jan 16 #Javascript
Bootstrap面板使用方法
Jan 16 #Javascript
codeMirror插件使用讲解
Jan 16 #Javascript
微信小程序 图片边框解决方法
Jan 16 #Javascript
微信小程序 scroll-view隐藏滚动条详解
Jan 16 #Javascript
微信小程序 video详解及简单实例
Jan 16 #Javascript
You might like
用文本文件制作留言板提示(上)
2006/10/09 PHP
DedeCms模板安装/制作概述
2007/03/11 PHP
PHP在字符串中查找指定字符串并删除的代码
2008/10/02 PHP
php.ini-dist 和 php.ini-recommended 的区别介绍(方便开发与安全的朋友)
2012/07/01 PHP
PHP explode()函数用法、切分字符串
2012/10/03 PHP
下拉列表多级联动dropDownList示例代码
2013/06/27 PHP
Laravel 5框架学习之Eloquent 关系
2015/04/09 PHP
对比分析php中Cookie与Session的异同
2016/02/19 PHP
laravel实现Auth认证,登录、注册后的页面回跳方法
2019/09/30 PHP
使图片旋转的3种解决方案
2013/11/21 Javascript
js图片预加载示例
2014/04/30 Javascript
js使用setTimeout实现定时炸弹的方法
2015/04/10 Javascript
AngularJS中的DOM操作用法分析
2016/11/04 Javascript
微信小程序加载更多 点击查看更多
2016/11/29 Javascript
js实现瀑布流效果(自动生成新的内容)
2017/03/16 Javascript
详解Angular 4.x NgTemplateOutlet
2017/05/24 Javascript
基于Vue生产环境部署详解
2017/09/15 Javascript
jQuery实现的页面遮罩层功能示例【测试可用】
2017/10/14 jQuery
微信小程序swiper使用网络图片不显示问题解决
2019/12/13 Javascript
JS继承定义与使用方法简单示例
2020/02/19 Javascript
使用Vant完成Dialog弹框案例
2020/11/11 Javascript
vue组件中节流函数的失效的原因和解决方法
2020/12/02 Vue.js
[01:03]DOTA2新的征程 你的脚印值得踏上
2014/08/13 DOTA
python使用urllib2实现发送带cookie的请求
2015/04/28 Python
Python 实现数据库更新脚本的生成方法
2017/07/09 Python
解决python3中自定义wsgi函数,make_server函数报错的问题
2017/11/21 Python
Python设计模式之命令模式原理与用法实例分析
2019/01/11 Python
详解python pandas 分组统计的方法
2019/07/30 Python
新手入门学习python Numpy基础操作
2020/03/02 Python
实习期自我鉴定
2013/10/11 职场文书
交通志愿者活动总结
2014/06/27 职场文书
医院合作意向书范本
2015/05/08 职场文书
利用js实现简单开关灯代码
2021/11/23 Javascript
Python学习之迭代器详解
2022/04/01 Python
Python可视化神器pyecharts绘制地理图表
2022/07/07 Python
Vue router配置与使用分析讲解
2022/12/24 Vue.js