环形链表

概念

  循环链表是另一种形式的链式存储结构。它的特点是表中最后一个结点的指针域指向头结点,整个链表形成一个环。

代码

节点对象

class Boy {

  private int no;// 编号

  private Boy next; // 指向下一个节点,默认null

  public Boy(int no) {
    this.no = no;
  }

  public int getNo() {
    return no;
  }

  public void setNo(int no) {
    this.no = no;
  }

  public Boy getNext() {
    return next;
  }

  public void setNext(Boy next) {
    this.next = next;
  }

}
// 创建一个环形的单向链表
class CircleSingleLinkedList {
  // 创建一个first节点,当前没有编号
  private Boy first = null;

  // 添加小孩节点,构建成一个环形的链表
  public void addBoy(int nums) {
    if(nums < 1){
      System.out.println("数据不正确");
      return;
    }
    Boy curBoy = null;
    for (int i = 1; i <= nums; i++){
      Boy boy = new Boy(i);
      if(i == 1){
        first = boy;
        first.setNext(first);
        curBoy = first;
      }else {
        curBoy.setNext(boy);
        boy.setNext(first);
        curBoy = boy;
      }
    }
  }

  // 遍历当前的环形链表
  public void showBoy() {
   if(first == null){
     System.out.println("没有任何小孩");
     return;
   }
   Boy curBoy = first;
   while (true){
     System.out.printf("小孩的编号%d \n",curBoy.getNo());
     if(curBoy.getNext() == first){
       break;
     }
     curBoy = curBoy.getNext();
   }
  }
}

案例

  Josephu  问题为:设编号为1,2,… n的n个人围坐一圈,约定编号为k(1<=k<=n)的人从1开始报数,数到m 的那个人出列,它的下一位又从1开始报数,数到m的那个人又出列,依次类推,直到所有人出列为止,由此产生一个出队编号的序列。

代码

 /**
   *根据用户的输入,计算出小孩出圈的顺序
   * 
   * @param startNo
   *            表示从第几个小孩开始数数
   * @param countNum
   *            表示数几下
   * @param nums
   *            表示最初有多少小孩在圈中
   */
  public void countBoy(int startNo, int countNum, int nums) {
    if( first == null || startNo < 1 || startNo > nums){
      System.out.println("数据不合法");
      return;
    }
    Boy temp = first;
    while (temp.getNext() != first){
      temp = temp.getNext();
    }
    //让first指向第一个小孩,temp指向最后一个
    for(int i = 0; i < startNo - 1; i++){
      first = first.getNext();
      temp = temp.getNext();
    }
    while (first != temp){
      for (int i = 0; i < countNum - 1; i++){
        first = first.getNext();
        temp = temp.getNext();
      }
      System.out.printf("小孩%d出圈\n",first.getNo());
      first = first.getNext();
      temp.setNext(first);
    }
    System.out.printf("最后留在圈中的小孩编号%d\n",first.getNo());
  }

测试

   CircleSingleLinkedList circleSingleLinkedList = new CircleSingleLinkedList();
    circleSingleLinkedList.addBoy(5);
    circleSingleLinkedList.showBoy();
    circleSingleLinkedList.countBoy(1,2,5);

环形链表

上一篇:7.21总结


下一篇:关于本站