使用单向循环链表解决约瑟夫问题

public class JosephProblem {

    /**
     * 使用单向循环链表解决约瑟夫问题
     */

    public static void main(String[] args) {
        // 造数据
        OneWayCircular oneWayCircular = new OneWayCircular();
        oneWayCircular.insertNode(0);
        oneWayCircular.insertNode(1);
        oneWayCircular.insertNode(2);
        oneWayCircular.insertNode(3);
        oneWayCircular.insertNode(4);
        oneWayCircular.insertNode(5);
        oneWayCircular.insertNode(6);
        oneWayCircular.insertNode(7);
        oneWayCircular.insertNode(8);
        oneWayCircular.insertNode(9);
        System.out.println("原列表值:" + oneWayCircular.toString());

        // 第6位出列,从0开始数,报到6弹出
        OneWayCircularNode preNode = oneWayCircular.headNode;
        for(;;){
            for(int i = 0; i < 5; i++){
                preNode = preNode.nextNode; // 这就是要弹出的节点的前一个节点
            }
            // 如果当前节点的下一个节点是他自己,则表示只剩最后一个节点了
            if (preNode.nextNode == preNode){
                System.out.println("最后剩余节点是:[" + preNode.value + "]");
                break;
            }
            int curValue = preNode.nextNode.value; // 弹出节点的value
            // 弹出节点是原来的头节点
            if (preNode.nextNode == oneWayCircular.headNode){
                // 将头节点移交给下一节点
                oneWayCircular.headNode = oneWayCircular.headNode.nextNode;
            }
            preNode.nextNode = preNode.nextNode.nextNode; // 弹出节点前一节点的下一节点替换成弹出节点的下一节点
            preNode = preNode.nextNode;
            System.out.println(oneWayCircular.toString() + ",当前弹出:" + curValue);
        }

    }

}
class OneWayCircular{
    public OneWayCircularNode headNode;

    /**
     * 只支持尾节点插入
     * @param value
     */
    public void insertNode(int value){
        OneWayCircularNode node = new OneWayCircularNode(value);
        if (headNode == null){
            headNode = node;
            headNode.nextNode = headNode;
        } else {
            OneWayCircularNode curNode = headNode;
            while (curNode.nextNode != headNode){
                curNode = curNode.nextNode;
            }
            curNode.nextNode = node;
            node.nextNode = headNode; // 首尾相连
        }
    }

    @Override
    public String toString(){
        StringBuffer stringBuffer = new StringBuffer();
        if (headNode == null){
            stringBuffer.append("OneWayCircularNode is null");
        } else {
            OneWayCircularNode curNode = headNode;
            while (curNode.nextNode != headNode){
                stringBuffer.append("[" + curNode.value + "]");
                curNode = curNode.nextNode;
            }
            stringBuffer.append("[" + curNode.value + "]");
        }
        return stringBuffer.toString();
    }
}
class OneWayCircularNode{
    public int value;
    public OneWayCircularNode nextNode;

    public OneWayCircularNode(int value){
        this.value = value;
        nextNode = null;
    }
}

结果:

原列表值:[0][1][2][3][4][5][6][7][8][9]
[0][1][2][3][4][5][7][8][9],当前弹出:6
[0][1][2][4][5][7][8][9],当前弹出:3
[0][2][4][5][7][8][9],当前弹出:1
[2][4][5][7][8][9],当前弹出:0
[4][5][7][8][9],当前弹出:2
[4][7][8][9],当前弹出:5
[4][7][8],当前弹出:9
[7][8],当前弹出:4
[8],当前弹出:7
最后剩余节点是:[8]

你可能感兴趣的:(数据结构和算法,链表,算法,数据结构)