环形链表及约瑟夫问题
接上篇的单联表,这篇主要写一下环形链表和约瑟夫问题
-
环形链表
环形链表的思路: 把传进来的链表遍历到尾巴,然后尾部的next指向头部即可
//把传进来的链表变成环形链表
public Student cirleLink(Student head){
Student temp = head;
while (true){
if(temp.next == null){
break;
}
temp = temp.next;
}
temp.next = head;
return head;
}
-
约瑟夫问题
/** * 约瑟夫问题 * @param head 储存数据的链表 * @param m 每隔M个就干掉 * @param no 从编号No开始算起 * @return */ public ArrayList josephu(Student head,int m,int no){ if (head.next == null){ return null; } //创建一个存放编号的数组 ArrayList<Integer> noArray = new ArrayList<>(); //创建一个辅助指针,用来储存被干掉的节点之前的一个节点 Student temp = null; //把传进来的head变成环形链表,这里head.next是去掉头部 Student circle = cirleLink(head.next); //从指定编号算起 while (true){ if(circle.no == no){ break; } circle = circle.next; } while (true){ //如果circle的下一个以及下下个都等于temp的话,说明这个环形链表只剩一个节点 if(circle.next == temp && circle.next.next == temp){ noArray.add(temp.no); break; } //循环每隔 m 个数要干掉的节点的前一个 for (int i = 0; i < m - 1; i++) { //当 i 循环到最后一个的时候,此时的temp等于要被干掉的节点的前一个 temp = circle; if(i == m - 2){ //放入要被干掉的节点的编号 noArray.add(circle.next.no); //将circle的下一个节点指向下下个节点上,这样被干掉的节点就不会再被指向了 circle.next = circle.next.next; break; } //往后移 circle = circle.next; } //干掉节点之后,circle往后移动一个然后继续 circle = circle.next; } return noArray; }
灵魂画图