1. 程式人生 > >連結串列--約瑟夫環

連結串列--約瑟夫環

/* * 雙向連結串列:在連結串列的基礎上進行改進 * 特徵:首尾相連,即最後一個節點指向第一個節點 * 另外:新增一個length屬性 * * */ /* * 定義一個node節點 * element 節點名稱 * next 指向下個節點的指標 * */ function Node(element){ this.element = element; this.next = null; } /* * 建立節點 * */ function
LList(){
this.head = new Node('head'); // 自己指向自己,形成一個環 this.head.next = this.head; this.length = 0; } /* * 根據節點名稱item查詢節點 * item 要查詢的節點的名稱 * * 實現過程: * 先找到首個節點(不為空),然後比較這個節點和名稱和要查詢的節點名稱是否一致 * 如果不一致,就將這個首個節點的下一個節點(不能為空)賦值給它, * 直到找到為止 * */
LList.prototype.find = function (item) { // 找到第一個節點,也就是當前的節點 let curNode = this.head; // 如果當前節點不為空 && 名稱與查詢節點名稱不相同 // 那麼指向下一個節點,並且迭代 while( curNode !== null && curNode.element !== item ) { curNode = curNode.next; } // 返回找到的節點
return curNode; } /* * 在已有節點item後面新增一個新節點newElement * newElement 新節點的名稱 * item 要插入到節點後的節點名稱 * * 實現過程: * 1.建立新節點newElement * 2.找到item的節點 * 3.將item.next 賦值給新節點 newElement.next * 即 newElement.next = item.next * 4.item.next 指向新節點 newElement * 即 item.next = newElement * */ LList.prototype.insertAfter = function (newElement, item) { // 1.建立新節點newElement newElement = new Node(newElement); // 2.找到item的節點 item = this.find(item); // 3.將item.next 賦值給新節點 newElement.next newElement.next = item.next; // 4.item.next 指向新節點 newElement item.next = newElement; this.length++; } /* * 找到當前節點的前一個節點 * item 當前節點的名稱 * * 實現過程: * 1.找到首個節點(不為空) * 2.這個節點的下一個節點的名稱和要查詢的節點相同,就返回 * 否則,繼續迭代 * * */ LList.prototype.findPrevious = function (item) { let curNode = this.head; while(curNode !== null && curNode.next.element !== item) { curNode = curNode.next; } return curNode; } /* * 刪除連結串列中的某個節點 * item : 要刪除的節點的名稱 * 實現過程: * 1.找到要刪除節點的前一個節點 * 2.將前一個節點的下一個節點指向當前節點的下一個節點 * */ LList.prototype.remove = function (item) { // 1.找到要刪除節點的前一個節點 let previousNode = this.findPrevious(item); previousNode.next = this.find(item).next; this.length--; } /* * 打印出整個連結串列中的所有節點 * * * */ LList.prototype.display = function () { let result = []; if(this.length === 0) return [this.head.element]; let curNode = this.head; while( curNode !== null && curNode.next.element !== 'head'){ result.push( curNode.element ); curNode = curNode.next; } result.push(curNode.element); return result; } killGame(41, 3); /* * 殺人遊戲 * num 一共多少人 * step 每隔多少人殺人 * * 實現過程 * 1,形成41人的約瑟夫環 * 2,每個3三人,刪除一個 * 3,最後剩下的兩位就是倖存者 * */ function killGame(num, step) { let iNow = 0; // 1,形成41人的約瑟夫環 let obj = new LList(); obj.insertAfter(1, 'head'); for ( let i = 1; i < num; i++ ) { obj.insertAfter(i + 1, i); } // 當前的節點 let curNode = 'head'; kill(); // 2,每個3三人,刪除一個 function kill(){ if(obj.length < step) return; iNow++; // 尋找下一個節點 curNode = obj.find(curNode).next.element; // 如果下一個節點是head,也就是說開始新的一輪殺人比賽 if(curNode === 'head'){ curNode = obj.find(curNode).next.element; } if(iNow === step){ let removeNode = curNode; // 殺掉當前這個為三的人,然後執行之前的一個,再開始迭代 curNode = obj.findPrevious(curNode).element; obj.remove(removeNode); iNow = 0; } arguments.callee(); } let luckyPerson = obj.display(); console.log('倖存的人是:' + luckyPerson[1] + ',' + luckyPerson[2]); }