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 相关文章推荐
点击文章内容处弹出页面代码
Oct 01 Javascript
预加载css或javascript的js代码
Apr 23 Javascript
基于jquery打造的百分比动态色彩条插件
Sep 19 Javascript
JavaScript高级程序设计(第3版)学习笔记7 js函数(上)
Oct 11 Javascript
JavaScript Ajax Json实现上下级下拉框联动效果实例代码
Nov 23 Javascript
GitHub上一些实用的JavaScript的文件压缩解压缩库推荐
Mar 13 Javascript
关于数据与后端进行交流匹配(点亮星星)
Aug 03 Javascript
BootStrap使用file-input插件上传图片的方法
Sep 05 Javascript
利用vue和element-ui设置表格内容分页的实例
Mar 02 Javascript
vue 实现在函数中触发路由跳转的示例
Sep 01 Javascript
vue中如何添加百度统计代码
Dec 19 Vue.js
vue-router中hash模式与history模式的区别
Jun 23 Vue.js
函数四种调用模式以及其中的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
用ADODB来让PHP操作ACCESS数据库的方法
2006/12/31 PHP
基于php-fpm的配置详解
2013/06/03 PHP
php实现统计邮件大小的方法
2013/08/06 PHP
php微信支付之APP支付方法
2015/03/04 PHP
phpmyadmin下载、安装、配置教程
2017/05/16 PHP
PHP设计模式之原型设计模式原理与用法分析
2018/04/25 PHP
php二维数组按某个键值排序的实例讲解
2019/02/15 PHP
js判断变量是否未定义的代码
2020/03/28 Javascript
js文件缓存之版本管理详解
2013/07/05 Javascript
JS父页面与子页面相互传值方法
2014/03/05 Javascript
javascript跨域的4种方法和原理详解
2014/04/08 Javascript
JavaScript输出当前时间Unix时间戳的方法
2015/04/06 Javascript
jQuery实现的背景动态变化导航菜单效果
2015/08/24 Javascript
JavaScript常用数组算法小结
2016/02/13 Javascript
javascript每日必学之条件分支
2016/02/17 Javascript
Javascript前端经典的面试题及答案
2017/03/14 Javascript
easyui-datagrid开发实践(总结)
2017/08/02 Javascript
Javasript设计模式之链式调用详解
2018/04/26 Javascript
layui字体图标 loading图标静止不旋转的解决方法
2019/09/23 Javascript
[34:39]Secret vs VG 2018国际邀请赛淘汰赛BO3 第二场 8.23
2018/08/24 DOTA
[51:17]Mineski vs Secret 2019国际邀请赛淘汰赛 败者组 BO3 第一场 8.22
2019/09/05 DOTA
深入解析Python中的集合类型操作符
2015/08/19 Python
关于Django外键赋值问题详解
2017/08/13 Python
Python项目跨域问题解决方案
2020/06/22 Python
如何解决cmd运行python提示不是内部命令
2020/07/01 Python
x-ua-compatible content=”IE=7, IE=9″意思理解
2013/07/22 HTML / CSS
产品质量承诺范本
2014/03/31 职场文书
城管大队整治方案
2014/05/06 职场文书
门店业绩提升方案
2014/06/08 职场文书
标准大学生职业生涯规划书写作指南
2014/09/18 职场文书
离婚协议书范文2015
2015/01/26 职场文书
建筑安全员岗位职责
2015/02/15 职场文书
2015年学校教育教学工作总结
2015/04/22 职场文书
退货证明模板
2015/06/23 职场文书
springboot如何初始化执行sql语句
2021/06/22 Java/Android
win10重装系统后上不了网怎么办 win10重装系统网络故障的解决办法
2022/07/23 数码科技