-------------------------------------
典型例题 23:数据结构问题---JOSEPHUS环解法
-------------------------------------
------------------
解法一:环链实现;
------------------
1 #include
2 #include
3 #include
4
5 typedef struct LNode {
6 int data;
7 struct LNode *link;
8 }Lnode,*LinkList;
9
10 //n为总人数,k为第一个开始报数的人,m为出列者喊到的数
11 void JOSEPHUS(int n,int k,int m)
12 {
13 /* p为当前结点 r为辅助结点,指向p的前驱结点 list为头节点*/
14 LinkList p,r,list = NULL;
15 int i = 0;
16 int count = 1;
17
18 /*建立循环链表*/
19 for(i=0;i
21 p=(LinkList)malloc(sizeof(LNode));
22 p->data = i+1;
23 if(list == NULL)
24 list = p;
25 else
26 r->link = p;
27 r=p;
28 }
29 p->link=list; /*使链表循环起来*/
30 p=list; /*使p指向头节点*/
31
32 /*把当前指针移动到第一个报数的人*/
33 for(i=0;i
35 r=p;
36 p=p->link;
37 }
38
39 /*循环地删除队列结点*/
40 while(p->link!=p)
41 {
42 for(i=0;i
44 r=p;
45 p=p->link;
46 }
47 r->link=p->link;
48 printf("第%d /t个被删除的元素:%4d /n",count,p->data);
49 free(p);
50 p=r->link;
51 count++;
52 }
53 printf("/n最后被删除的元素是:%4d /n",p->data);
54 }
55
56 int main()
57 {
58 JOSEPHUS(30,1,9);
59 return 0;
60 }
------------------
解法二:数学实现;
------------------
1 #include
2 int main(void)
3 {
4
5 int n, m, i, s=0;
6 printf ("N M = ");
7 scanf("%d%d", &n, &m);
8 for (i=2; i<=n; i++)
9 s=(s+m)%i;
10 printf ("The winner is %d/n", s+1);
11 return 0 ;
12 }
13
------------------
解法三:C++类实现;
------------------
////////////list.h/////////////////
1 #include
2 using namespace std;
3 typedef struct Lnode
4 {
5 Lnode *next;
6 int data;
7 }Lnode,*Lnodelist;
8
9 class List
10 {
11 protected:
12 int m_len;
13 Lnode* m_pHead;
14 int begin;
15 int interval;
16
17 public:
18 List(int n ,int k ,int m );
19 ~List();
20 void Print();
21 int JOSEPHUS();
22
23 };
////////////list.cc/////////////////
1 #include"list.h"
2 List::List(int n ,int k ,int m):m_len(0),begin(k),interval(m)
3 {
4 m_pHead = new Lnode;
5 if(m_pHead)
6 {
7 m_pHead->next = m_pHead;
8 }
9 Lnode* pTemp = m_pHead->next;
10 for(int i = 0 ; i < n ; i++ )
11 {
12 Lnode* pNew = new Lnode;
13 if(pNew)
14 {
15 pNew->data = i+1;
16 pTemp->next = pNew;
17 }
18 pTemp = pTemp->next ;
19 pNew = NULL;
20 }
21 pTemp->next = m_pHead;
22 m_len = n;
23 Print();
24 }
25
26 List::~List()
27 {
28 if(m_len)
29 {
30
31 while(m_pHead->next != m_pHead )
32 {
33 Lnode* pTemp = m_pHead->next;
34 m_pHead = m_pHead->next;
35 delete pTemp;
36 pTemp = NULL;
37 }
38 m_len=0;
39 }
40 }
41
42 void List::Print()
43 {
44 if(0 == m_len)
45 {
46 cout<<"Print error!"<
48 Lnode *pTemp = m_pHead->next;
49 while (m_pHead != pTemp)
50 {
51 cout<
52 pTemp = pTemp->next;
53 }
54 cout<
56 }
57
58 int List::JOSEPHUS()
59 {
60 if(!m_len)
61 {
62 cout<<"JOSEPHUS error!"<
64 }
65 Lnode* pTemp = m_pHead;
66 Lnode* ppTemp;
67 Lnode* pDelete = NULL;
68 //Find the first man (k)
69 for(int i = 0 ; i < begin-1 ;)
70 {
71 ppTemp = pTemp;
72
73 if(pTemp == m_pHead)
74 {
75 pTemp = pTemp->next;
76 continue;
77 }
78 pTemp = pTemp->next;
79 i++;
80 }
81 cout<<"The first one is:"<
83 while(m_len)
84 {
85 for(int j = 0 ; j < interval-1;)
86 {
87 ppTemp = pTemp;
88 if(pTemp == m_pHead)
89 {
90 pTemp = pTemp->next;
91 continue;
92 }
93
94 pTemp = pTemp->next;
95 j++;
96 }
97 if(pTemp == m_pHead)
98 {
99 pDelete = pTemp->next;
100 m_pHead->next = m_pHead->next->next;
101 ppTemp->next = m_pHead->next;
102 }
103 else
104 {
105 pDelete = pTemp;
106 ppTemp->next = pTemp->next;
107 }
108 m_len--;
109 cout<<30-m_len<<":/t"<
111 pTemp = ppTemp->next;
112 pDelete = NULL;
113 }
114 }
////////////main.cc/////////////////
1 #include"list.h"
2 int main()
3 {
4 List list(9,1,5);
5 list.JOSEPHUS();
6 return 0;
7 }
////////////Makefile/////////////////
1 CC=g++
2 main:list.o main.o
3 list.o:list.h
4 $(CC) -c list.cc
5 main.o:list.h
6 $(CC) -c main.cc
7 clean:
8 rm -f main *.o *~
9 .PHONE: clean
------------------------
haiping@ubuntu:~/program/wk0805$ ./a.out
第1 个被删除的元素: 9
第2 个被删除的元素: 18
第3 个被删除的元素: 27
第4 个被删除的元素: 6
第5 个被删除的元素: 16
第6 个被删除的元素: 26
第7 个被删除的元素: 7
第8 个被删除的元素: 19
第9 个被删除的元素: 30
第10 个被删除的元素: 12
第11 个被删除的元素: 24
第12 个被删除的元素: 8
第13 个被删除的元素: 22
第14 个被删除的元素: 5
第15 个被删除的元素: 23
第16 个被删除的元素: 11
第17 个被删除的元素: 29
第18 个被删除的元素: 17
第19 个被删除的元素: 10
第20 个被删除的元素: 2
第21 个被删除的元素: 28
第22 个被删除的元素: 25
第23 个被删除的元素: 1
第24 个被删除的元素: 4
第25 个被删除的元素: 15
第26 个被删除的元素: 13
第27 个被删除的元素: 14
第28 个被删除的元素: 3
第29 个被删除的元素: 20
最后被删除的元素是: 21
------------------------
haiping@ubuntu:~/program/wk0805$ ./a.out
N M = 30 9
The winner is 21
------------------------
haiping@ubuntu:~/program/wk0805$ ./main
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
The first one is:0
1: 9
2: 18
3: 27
4: 6
5: 16
6: 26
7: 7
8: 19
9: 30
10: 12
11: 24
12: 8
13: 22
14: 5
15: 23
16: 11
17: 29
18: 17
19: 10
20: 2
21: 28
22: 25
23: 1
24: 4
25: 15
26: 13
27: 14
28: 3
29: 20
30: 21