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 相关文章推荐
jQuery AJAX 调用WebService实现代码
Mar 24 Javascript
js 父窗口控制子窗口的行为-打开,关闭,重定位,回复
Apr 20 Javascript
基于jquery 的一个progressbar widge
Oct 29 Javascript
基于jquery的仿百度搜索框效果代码
Apr 11 Javascript
jquery插件lazyload.js延迟加载图片的使用方法
Feb 19 Javascript
Node.js中require的工作原理浅析
Jun 24 Javascript
JS实现让网页背景图片斜向移动的方法
Feb 25 Javascript
BootStrap智能表单demo示例详解
Jun 13 Javascript
Bootstrap3 Grid system原理及应用详解
Sep 30 Javascript
vue-router实现组件间的跳转(参数传递)
Nov 07 Javascript
Vue组件创建和传值的方法
Aug 17 Javascript
js制作提示框插件
Dec 24 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
用PHP调用Oracle存储过程
2006/10/09 PHP
php中的一个中文字符串截取函数
2007/02/14 PHP
PHP YII框架开发小技巧之模型(models)中rules自定义验证规则
2015/11/16 PHP
PHP实现绘制二叉树图形显示功能详解【包括二叉搜索树、平衡树及红黑树】
2017/11/16 PHP
浅谈laravel 5.6 安装 windows上使用composer的安装过程
2019/10/18 PHP
javascript显示选择目录对话框的代码
2008/11/10 Javascript
javascript中有趣的反柯里化深入分析
2012/12/05 Javascript
兼容IE和Firefox火狐的上下、左右循环无间断滚动JS代码
2013/04/19 Javascript
解析window.open的使用方法总结
2013/06/19 Javascript
简单讲解jQuery中的子元素过滤选择器
2016/04/18 Javascript
js倒计时简单实现代码
2016/08/11 Javascript
javascript深拷贝和浅拷贝详解
2017/02/14 Javascript
JS 调试中常见的报错问题解决方法
2017/05/20 Javascript
es6 字符串String的扩展(实例讲解)
2017/08/03 Javascript
解决html-jquery/js引用外部图片时遇到看不了或出现403的问题
2017/09/22 jQuery
vue cli2.0单页面title修改方法
2018/06/07 Javascript
JS使用tween.js动画库实现轮播图并且有切换功能
2018/07/17 Javascript
浅谈layui里的上传控件问题
2019/09/26 Javascript
vue中重定向redirect:‘/index‘,不显示问题、跳转出错的完美解决
2020/09/28 Javascript
[52:06]FNATIC vs NIP 2019国际邀请赛小组赛 BO2 第二场 8.16
2019/08/19 DOTA
Python Socket编程入门教程
2014/07/11 Python
对python中return和print的一些理解
2017/08/18 Python
python实现基于SVM手写数字识别功能
2020/05/27 Python
Python编程pygame模块实现移动的小车示例代码
2018/01/03 Python
利用python下载scihub成文献为PDF操作
2020/07/09 Python
Python应用自动化部署工具Fabric原理及使用解析
2020/11/30 Python
HTML5本地数据库基础操作详解
2016/04/26 HTML / CSS
Zalando Lounge瑞士:时尚与生活方式购物俱乐部
2020/03/12 全球购物
员工拾金不昧表扬信
2014/01/09 职场文书
《第一次抱母亲》教学反思
2014/04/16 职场文书
村抢险救灾方案
2014/05/09 职场文书
导游词之宁夏贺兰山岩画
2019/11/08 职场文书
解析CSS 提取图片主题色功能(小技巧)
2021/05/12 HTML / CSS
Vue图片裁剪组件实例代码
2021/07/02 Vue.js
英镑符号 £
2022/02/17 杂记
了解Kubernetes中的Service和Endpoint
2022/04/01 Servers