数据结构复习之链表———约瑟夫问题案例

* 约瑟芬问题,俗称丢手帕问题:

* 有n个人围成一圈,从指定的第一个人开始从1依次报数,
* 数到m的那个人出列,接着下一个人从1开始接着报数,
* 直到最后只剩下一个人出列,问最后出列的是第几个人?

1.单链表解决:

 1 /**
 2  * 结点类
 3  * @author Administrator
 4  * @since 2015年8月8日 下午4:10:20
 5  * @version
 6  * @since JDK 1.6
 7  */
 8 class Node{
 9     private int val;
10     private Node next;
11     public int getVal() {
12         return val;
13     }
14     public void setVal(int val) {
15         this.val = val;
16     }
17     public Node getNext() {
18         return next;
19     }
20     public void setNext(Node next) {
21         this.next = next;
22     }
23 }
 1 /**
 2  * 采用单向链表解决
 3  * @author Administrator
 4  * @since 2015年8月8日 下午4:05:05
 5  * @version
 6  * @since JDK 1.6
 7  */
 8 class Way1{
 9     private int serialNo=1;
10     private Node head;//定义一个头指针,并非是第一个结点
11
12     public void createLink(int n){//创建链表——约瑟夫环
13         head=new Node();
14         head.setNext(null);
15         Node rear=new Node();
16         rear=head;
17         for(int i=0;i<n;i++){
18             Node newNode=new Node();
19             newNode.setVal(i+1);
20             newNode.setNext(null);
21             rear.setNext(newNode);
22             rear=newNode;
23         }
24     }
25
26     public void printLink(){
27         Node p=head.getNext();
28         System.out.print("约瑟夫环:");
29         while(p!=null){
30             System.out.print(p.getVal()+"->");
31             p=p.getNext();
32         }
33         System.out.println("end");
34     }
35
36     /**
37      * 解约瑟夫环
38      * @param startIndex 第一开始报数的人序号
39      * @param count      计数  for 出列
40      */
41     public void display(int startIndex,int count){
42         Node p=head;
43         for(int i=0;i<startIndex;i++){//移动到第一个开始报数的人的位置
44             p=p.getNext();
45         }
46
47         while(head.getNext()!=null){
48             for(int j=0;j<count-2;j++){
49                 p=p.getNext();
50                 if(p==null){
51                     p=head.getNext();
52                 }
53             }
54             delete(p);//删除p的后继结点
55             if(p.getNext()==null){
56                 p=head.getNext();
57             }else{
58                 p=p.getNext();
59             }
60         }
61
62
63     }
64
65     /**
66      * @param p
67      */
68     private void delete(Node p) {
69         Node q=p.getNext();
70         if(q==null){//p是尾结点,删除第一个结点
71             Node outman=head.getNext();
72             head.setNext(outman.getNext());
73             System.out.println("序号"+(serialNo++)+"-----第"+outman.getVal()+"个人出列");
74         }else{
75             p.setNext(q.getNext());
76             System.out.println("序号"+(serialNo++)+"-----第"+q.getVal()+"个人出列");
77         }
78
79     }
80 }

2.循环链表解决:

 1 /**
 2  * 采用循环链表解决
 3  * @author Administrator
 4  * @since 2015年8月8日 下午5:23:04
 5  * @version
 6  * @since JDK 1.6
 7  */
 8 class Way2{
 9     private Node head;//头指针
10     private int serialNo=1;
11
12     public void createLink(int n){
13         head=new Node();
14         head.setNext(null);
15         Node rear=new Node();
16         rear=head;
17         for(int i=0;i<n;i++){
18             Node newNode=new Node();
19             newNode.setVal(i+1);
20             newNode.setNext(head);
21             rear.setNext(newNode);
22             rear=newNode;
23             rear.setNext(head.getNext());
24         }
25     }
26
27
28     public void printLink(){
29         Node p=head.getNext();
30         do{
31             System.out.print("约瑟夫环:"+p.getVal()+"->");
32             p=p.getNext();
33         }while(p!=head.getNext());
34         System.out.println("end");
35     }
36
37     /**
38      * 解约瑟夫环
39      * @param startIndex 第一开始报数的人序号
40      * @param count      计数  for 出列
41      */
42     public void display(int startIndex,int count){
43         Node p=head;
44         for(int i=0;i<startIndex;i++){
45             p=p.getNext();
46         }
47         while(head.getNext()!=null){
48             for(int j=0;j<count-2;j++){
49                 p=p.getNext();
50             }
51             delete(p);//delete the rear node of p
52             p=p.getNext();
53         }
54     }
55
56
57     /**
58      * @param p
59      */
60     private void delete(Node p) {
61         Node q=p.getNext();
62
63         if(p==q){
64             head.setNext(null);
65             System.out.println("序号"+(serialNo++)+"-----第"+q.getVal()+"个人出列");
66         }else if(q==head.getNext()){
67             head.setNext(q.getNext());
68             p.setNext(head.getNext());
69             System.out.println("序号"+(serialNo++)+"-----第"+q.getVal()+"个人出列");
70         }else{
71             p.setNext(q.getNext());
72             System.out.println("序号"+(serialNo++)+"-----第"+q.getVal()+"个人出列");
73         }
74     }
75
76 }
时间: 2024-08-07 14:51:47

数据结构复习之链表———约瑟夫问题案例的相关文章

【数据结构复习】链表的倒置(头插法倒置)

#include <bits/stdc++.h> using namespace std; typedef int ElemType; struct LNode{ ElemType data; LNode *next; }; LNode *head,*tail; void init(){ head = (LNode*)malloc(sizeof(LNode)); head->next = NULL; tail = head; } void input_data(){ int x; cin

数据结构线性表链表的C语言实现

                                                                                      数据结构线性表链表的C语言实现      说明:线性表是一种最简单的线性结构,也是最基本的一种线性结构,所以它不仅是学习中的重点,也是应用开发非常常用的一种数据结构.它可以分为顺序表和链表.它的主要操作是数据元素的插入,删除,以及排序等.接下来,本篇文章将对线性表链表的基本操作和运用进行详细的说明(包含在源代码的注释中),并给

C#数据结构-单链表

理论基础: 链表是用一组任意的存储单元来存储线性表中的数据元素. 如果结点的引用域只存储该结点直接后继结点的存储地址,则该链表叫单链表(Singly Linked List). 单链表由头引用H唯一确定.头引用指向单链表的第一个结点,也就是把单链表第一个结点的地址放在H中. C#实现: 1接口 引用线性表的接口IListDS<T> 2实现 首先,必须定义一个单链表的节点类.  1 public class Node<T> 2    { 3        private T data

数据结构复习之--“插入排序”-JAVA实现

菜鸟中的菜鸟一枚,面临找工作,复习下数据结构,写的插入排序算法记录一下,每天写一点,不断积累吧! import java.util.Scanner; /** * * @author DL * 数据结构复习之插入排序练习程序 * */ public class SortTest { public static void main(String [] args){ Scanner sc = new Scanner(System.in); int totalNums = sc.nextInt();//

数据结构实验之链表五:单链表的拆分

数据结构实验之链表五:单链表的拆分 Time Limit: 1000MS Memory limit: 65536K 题目描述 输入N个整数顺序建立一个单链表,将该单链表拆分成两个子链表,第一个子链表存放了所有的偶数,第二个子链表存放了所有的奇数.两个子链表中数据的相对次序与原链表一致. 输入 第一行输入整数N;: 第二行依次输入N个整数. 输出 第一行分别输出偶数链表与奇数链表的元素个数: 第二行依次输出偶数子链表的所有数据: 第三行依次输出奇数子链表的所有数据. 示例输入 10 1 3 22

数据结构实验之链表三:链表的逆置

数据结构实验之链表三:链表的逆置 Time Limit: 1000MS Memory limit: 65536K 题目描述 输入多个整数,以-1作为结束标志,顺序建立一个带头结点的单链表,之后对该单链表的数据进行逆置,并输出逆置后的单链表数据. 输入 输入多个整数,以-1作为结束标志. 输出 输出逆置后的单链表数据. 示例输入 12 56 4 6 55 15 33 62 -1 示例输出 62 33 15 55 6 4 56 12 提示 不得使用数组. 来源 示例程序 /*************

数据结构实验之链表四:有序链表的归并

数据结构实验之链表四:有序链表的归并 Time Limit: 1000MS Memory limit: 65536K 题目描述 分别输入两个有序的整数序列(分别包含M和N个数据),建立两个有序的单链表,将这两个有序单链表合并成为一个大的有序单链表,并依次输出合并后的单链表数据. 输入 第一行输入M与N的值: 第二行依次输入M个有序的整数: 第三行依次输入N个有序的整数. 输出 输出合并后的单链表所包含的M+N个有序的整数. 示例输入 6 5 1 23 26 45 66 99 14 21 28 5

【数据结构】静态链表

数据结构之静态链表实现 前言 静态链表,是一种巧妙的数据结构实现方式. 静态链表: 每个节点有一个数据域(data),用来存放有用的数据信息: 还有一个下标域(cur),用来指示下一个元素的下标位置. 我们都知道链式线性表的优势在于插入和删除元素,时间复杂度都是O(1),因为不需要像顺序存储结构的线性表那样在插入和删除时需要移动大量的元素. 而静态链表的实现就弥补了这样的不足,我们以下标的方式来代替链式结构中使用的的指针,从而达到减少时间复杂度的功能. 分析 实现静态链表 下面是代码,实现了最基

数据结构与算法-链表的基本操作---ShinPans

//链表操作:建立.插入.删除.查找.倒置.删除等基本操作 #include<stdio.h> #include<stdlib.h> typedef  struct LNode {       int data;       structLNode *next; }LNode,*Llist; LNode *creat_head();//创建一个空表 void creat_list(LNode *,int);//创建一个长度为n的线性链表 void insert_list(LNode