1.1.算法描述
Even算法的过程描述如下
(1)求出最大的活动整数m
(2)交换m和其箭头所掼向的与其相信的整数。
(3)交换所有满足p>m的整数的p的方向。
1.2.算法分析
由于每个数字还带有方向这个属性,因些需要使用自己定义数据类型。本算法中用一个结构来表示,结构有两个域,一个代表值,一个代码方向。
算法最大的难点在于,一是判断当前元素是否活动,二是需要找到最大的活动的元素。
通过试验生成过程,可以发现,其中最活跃的元素就是最大的那个元素,因为每交换一个比它小的元素,它都会由不活动状态变成活动状态。因此,在算法的实现上,要格外关注最大的那个元素。事实上,整个算法主要是在将最大的那个元素进行移动。也对最大的那个元素的位置进行了标识。
判断当前元素是否活动,有三种情况是不活动的:
1. 该元素在第一位,并且指向左边。
2. 该元素在最后一位,并且指向右边。
3. 该元素在中间,并且指向的元素比它要大。
通过这三个条件,就可判断当前元素是否活动的。
考虑扩展性,可排列的元素可以不从0开始,也可以不连续。因为排列归根结底是对元素的下标进行排列。因些可考虑让用户自己定义打印算法。
1
#ifndef U8
2
#define U8 unsigned char
3
#endif // U8
4
5
#define DIR_LEFT 0 // 箭头向左
6
#define DIR_RIGHT 1 // 箭头向右
7
8
// 用于输出 一个排列
9
typedef void(*AdjustCallback)(void *const, int size);
10
11
// 一个排列列的元素,它包括数字和这个数字上箭头的方向
12
typedef struct Item
13
{
14
int num;
15
U8 direct;
16
};
17
18
// 默认输出排列的函数
19
void def_printarray(void *const array, int size)
20
{
21
if(array == NULL)
22
return;
23
for(int i=0;i<size;i++)
24
{
25
cout<<((Item **)array)[i]->num<<' ';
26
}
27
cout<<endl;
28
}
29
30
// 用Even方法生成排列的类
31
class Even
32
{
33
private:
34
Item **array; // 一队排列数
35
int size; // 排列数,表明是几排列。如5排列
36
private:
37
void initarray(); // 初始化排列
38
void deletearray(); // 删除排列的元素
39
void printarray(); // 打印排列元素
40
U8 isMaxActive(Item *item); // 判断最大的元素是否活动
41
U8 isItemActive(int index); // 判断当前元素是否活动
42
U8 forward(int index); // 数列元素的一次交换,它是将当前元素与前面(或后面)的元素进行交换,具体根据箭头来判断
43
void swap(Item **p1, Item **p2); // 具体的交换操作
44
int getMaxActiveIndex(); // 获取数列中,最大的活动的元素
45
void adjustPrimar(int index); // 将比当前元素大的元素的方向换向
46
public:
47
Even();
48
Even(int size);
49
virtual ~Even();
50
void gen(); // 产生排列的主函数
51
inline int getsize()const;
52
inline void setsize(int size);
53
54
AdjustCallback _printarray; // 打印数列的回调函数,支持用户自定义
55
};
56
57
Even::Even()
58
{
59
array = NULL;
60
size = 0;
61
_printarray = &def_printarray;
62
}
63
64
Even::Even(int size)
65
{
66
array = NULL;
67
this->size = size;
68
_printarray = &def_printarray;
69
}
70
71
Even::~Even()
72
{
73
//
74
}
75
76
int Even::getsize()const
77
{
78
return size;
79
}
80
81
void Even::setsize(int size)
82
{
83
deletearray();
84
this->size = size;
85
}
86
87
void Even::printarray()
88
{
89
if(array == NULL)
90
return;
91
for(int i=0;i<size;i++)
92
{
93
cout<<array[i]->num<<' ';
94
}
95
cout<<endl;
96
}
97
98
void Even::deletearray()
99
{
100
if(array == NULL)
101
return;
102
103
for(int i=0;i<size;i++)
104
delete array[i];
105
delete []array;
106
array = NULL;
107
}
108
109
void Even::initarray()
110
{
111
if(size <= 0)
112
return;
113
114
deletearray();
115
116
array = new Item* [size];
117
Item *curr;
118
119
//
120
for(int i=0;i<size;i++)
121
{
122
curr = new Item; //(Item *)malloc(sizeof(curr));
123
curr->num = i;
124
curr->direct = 0; //<-
125
array[i] = curr;
126
}
127
}
128
129
void Even::gen()
130
{
131
if(size <= 0)
132
return;
133
initarray();
134
135
Item &max = *(array[size - 1]);
136
int currindex = size - 1;
137
int activeindex = -1;
138
U8 dir;
139
140
//printarray();
141
_printarray(array, size);
142
do{
143
//
144
while(isMaxActive(&max))
145
{
146
//exchange
147
dir = forward(currindex);
148
//printarray();
149
_printarray(array, size);
150
// adjust
151
if(dir == DIR_LEFT)
152
currindex--;
153
else currindex++;
154
}
155
156
//
157
activeindex = getMaxActiveIndex();
158
if(activeindex == -1)
159
break;
160
161
dir = forward(activeindex);
162
163
//
164
if(dir == DIR_LEFT)
165
activeindex--;
166
else activeindex++;
167
adjustPrimar(activeindex);
168
//printarray();
169
_printarray(array, size);
170
171
}while(activeindex != -1);
172
}
173
174
U8 Even::isMaxActive(Item *item)
175
{
176
return (item->direct == DIR_LEFT && (item != array[0])) ||
177
(item->direct == DIR_RIGHT && (item != array[size - 1]));
178
}
179
180
U8 Even::isItemActive(int index)
181
{
182
if(index == 0 && array[index]->direct == DIR_LEFT)
183
return 0;
184
else if(index == size-1 && array[index]->direct == DIR_RIGHT)
185
return 0;
186
if(array[index]->direct==DIR_LEFT && array[index] > array[index-1])
187
return 1;
188
if(array[index]->direct==DIR_RIGHT && array[index] > array[index+1])
189
return 1;
190
return 0;
191
}
192
U8 Even::forward(int index)
193
{
194
Item *item = array[index];
195
if(item->direct == DIR_LEFT && index > 0)
196
{
197
swap(&array[index], &array[index - 1]);
198
return DIR_LEFT;
199
}
200
else if(item->direct == DIR_RIGHT && index < size - 1)
201
{
202
swap(&array[index], &array[index + 1]);
203
return DIR_RIGHT;
204
}
205
return 0;
206
}
207
208
void Even::swap(Item **p1, Item **p2)
209
{
210
Item *tmp = *p2;
211
*p2 = *p1;
212
*p1 = tmp;
213
}
214
215
int Even::getMaxActiveIndex()
216
{
217
int index = -1;
218
Item *currmax = NULL;
219
for(int i=0;i<size;i++)
220
{
221
if(isItemActive(i) && (currmax == NULL || currmax->num < array[i]->num))
222
{
223
index = i;
224
currmax = array[i];
225
}
226
}
227
return index;
228
}
229
230
void Even::adjustPrimar(int index)
231
{
232
for(int i=0;i<size;i++)
233
{
234
if(i==index) continue;
235
if(array[i]->num > array[index]->num)
236
array[i]->direct = (array[i]->direct == DIR_LEFT? DIR_RIGHT:DIR_LEFT);
237
}
238
}
239
240
void test1();
241
void test2();
242
void my_printarray(void *const array, int size);
243
244
int main(int argc, char *argv[])
245
{
246
/* int size, selcount;
247
cin>>size;
248
if (size <= 2)
249
return -1;
250
251
Even e;
252
e.setsize(size);
253
e.gen();
254
*/
255
// test1();
256
test2();
257
system("PAUSE");
258
return 0;
259
}
260
261
void test1()
262
{
263
cout<<"请输入排列的阶数:";
264
int size, selcount;
265
cin>>size;
266
if (size <= 2)
267
return;
268
269
Even e;
270
e.setsize(size);
271
e.gen();
272
}
273
274
int arrTarget[] = {12, 9, 55, 34, 1};
275
void test2()
276
{
277
cout<<"原数列为:";
278
for(int i=0;i<sizeof(arrTarget)/sizeof(int);i++)
279
cout<<arrTarget[i]<<",";
280
cout<<endl;
281
282
Even e;
283
e.setsize(5);
284
e._printarray = &my_printarray;
285
e.gen();
286
cout<<endl;
287
}
288
289
void my_printarray(void *const array, int size)
290
{
291
int index;
292
for(int i=0;i<size;i++)
293
{
294
index = ((Item **)array)[i]->num;
295
cout<<arrTarget[index]<<' ';
296
}
297
cout<<endl;
298
}

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

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

233

234

235

236

237

238

239

240

241

242

243

244

245

246

247

248

249

250

251

252

253

254

255

256

257

258

259

260

261

262

263

264

265

266

267

268

269

270

271

272

273

274

275

276

277

278

279

280

281

282

283

284

285

286

287

288

289

290

291

292

293

294

295

296

297

298
