1
/*
2
求解约瑟夫问题:n个猴子要选大王,方法是:所有猴子安1,2,
,n编号围坐一圈,
3
从第一号开始报数,凡报到m号的退出圈外,如此循环报数,直到圈内剩下一只猴子(大王)
4
*/
5
6
/**************************************
7
线性表的顺序存储--顺序表
8
9
第i个元素的存储位置紧接在i-1个元素的存储位置后面,假定线性表的元素类型为ElemType,则
10
每个元素所占的存储空间大小(即字节数)为sizeof(ElemType),整个线性表所占的存储空间大
11
小为n*sizeof(ElemType),其中n表示线性表的长度
12
*************************************/
13
14
15
#include "stdafx.h"
16
#define MaxSize 10 //线性表的长度
17
typedef char ElemType; //定义线性表的元素类型为 char
18
struct List
19
{
20
ElemType list[MaxSize];
21
int size;
22
};
23
24
//*************************************************************置空表setnull()
25
void setnull(struct List *p)
26
{
27
p->size=0;
28
}
29
30
31
//**************************************************************插入结点insert()
32
void insert(struct List *p,ElemType x,int i)
33
{
34
int j;
35
if(i<1||i>p->size+1) //例如: size=1或者4
36
printf("位置参数不正确,不能进行插入操作!\n");
37
else
38
{
39
p->size++; //(p->size)++
40
for(j=p->size-1;j>=i;j--)
41
p->list[j]=p->list[j-1]; //注意下标和size的关系j=size-1
42
p->list[j]=x;
43
44
}
45
}
46
//****************************************************************删除结点del()
47
void del(struct List *p,int i)
48
{
49
int j;
50
if(i>p->size||i<1)
51
printf("位置参数不正确,不能进行删除操作!\n");
52
else
53
{
54
for(j=i-1;j<p->size-1;j++)
55
p->list[j]=p->list[j+1];
56
p->size--;
57
}
58
}
59
60
//****************************************************************返回长度
61
int length(struct List *p)
62
{
63
return(p->size);
64
}
65
//************************************************************取表中的第i个结点
66
int get(struct List *p,int i)
67
{
68
if (i>p->size)
69
return(-1);
70
else
71
return(p->list[i-1]);
72
}
73
74
//****************************************************************按值查找
75
int locate(struct List *p,ElemType x)
76
{
77
int i=0;
78
while (i<p->size && p->list[i]!=x) i++;
79
if (i==p->size)
80
return(-1);
81
else
82
return(i+1);
83
}
84
85
86
87
//****************************************************************显示顺序表
88
void display(struct List *p)
89
{
90
int j;
91
printf("\n");
92
if(p->size==0)
93
printf("该顺序表为空,不能显示!\n");
94
else
95
{
96
printf("顺序表:");
97
if(p->size==1) //只有一个结点的情况
98
printf("%d",p->list[p->size-1]);
99
else//有一个以上结点的情况
100
{
101
for(j=0;j<p->size-1;j++)
102
printf("%d->",p->list[j]);
103
printf("%d",p->list[j]);//显示最后一个结点
104
}
105
printf("\n");
106
}
107
}
108
109
//**********************************************************显示某结点的值disp_i()
110
111
void disp_i(struct List *p,int i)
112
{
113
if(i>p->size)
114
printf("该顺序表为空,不能显示!\n");
115
else
116
printf("第%i个结点的值是:%d\n",i,p->list[i-1]);//下标和插入的位置是不同的,“位置”-1=“下标”
117
}
118
119
void main()
120
{
121
int n=10,m=4,i,count;
122
struct List L;
123
setnull(&L);
124
for(i=1;i<=10;i++)
125
insert(&L,i,i); //下标和插入的位置是不同的,“位置”=“下标”+1
126
display(&L);
127
128
while(n>0)
129
{
130
for(i=1;i<=n;i++)
131
{
132
count++;
133
if(count==m)
134
{
135
disp_i(&L,i);//出到圈外去
136
del(&L,i);
137
count=0;
138
n--;//表示有n只猴子要退出到圈外,最后一个是大王
139
i--;//删除操作导致后面结点往前移动,
140
//例如:删除第4个,那么第5个落到第4个的位置,即从第4个位置开始计数
141
}
142
}
143
}
144
}
145
146
147
/*
148
运行结果如下:
149
150
顺序表:1->2->3->4->5->6->7->8->9->10
151
第4个结点的值是:4
152
第7个结点的值是:8
153
第2个结点的值是:2
154
第5个结点的值是:7
155
第2个结点的值是:3
156
第5个结点的值是:10
157
第4个结点的值是:9
158
第1个结点的值是:1
159
第2个结点的值是:6
160
第1个结点的值是:5
161
162
注意:因为删除结点时要移动数据,所以运行速度好慢,
163
应该把退出到圈外的猴子置值0来表示
164
*/

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

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164
