This repository has been archived by the owner on Apr 4, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2
/
ex_15.cpp
402 lines (348 loc) · 9.92 KB
/
ex_15.cpp
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
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
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
#include <iostream>
#include "stdio.h"
#include "stdlib.h"
using namespace std;
#define ERROR 0
#define OK 1
#define OVERFLOW -2
#define MAXSIZE 100000 //用户自己规定排序的数字的长度
typedef int Status;
typedef struct
{
int *r; // r[0]闲置
int length; //顺序表的总长度
}Sqlist;
//构造一个空线性表
Status InitSqlist(Sqlist &L)
{
L.r=(int *)malloc(MAXSIZE*sizeof(int)); //分配存储空间
if(!L.r)
{
printf("存储分配失败!");
exit(0);
} //存储分配失败
L.length=0;//初始长度为0
return OK;
}
//输入待排序整数
Status ScanfSqlist(int &N,Sqlist &L)
{
int i;
cout<<"请输入要排序的元素个数N: "<<endl;
cin>>N;
cout<<"请输入"<<N<<"个要排序的整数: "<<endl;
for(i=1;i<=N;i++)
cin>>L.r[i]; //输入待排序整数
printf("\n\n");
L.length=N; //存储线性表的长度
return OK;
}
//输出排序之后的数据
Status PrintfSqlist(int N,Sqlist L)
{
int i;
cout<<"数据个数:"<<L.length<<endl;//输出数据个数
cout<<"排序后的数据:(从左向右依次增大)"<<endl;//输出数据
for(i=1;i<=N;i++)
cout<<L.r[i]<<" ";
cout<<endl;
return OK;
}
//***************************************************************
// 直接插入排序
//***************************************************************
Status InsertSort(Sqlist &L) //参考课件
{
int i,j;
if(L.length==0)
{
printf("要排序的数据为空!");
return ERROR;
}
for(i=2;i<=L.length;i++)
{
if(L.r[i]<L.r[i-1]) //将L.r[i]插入有序子表
{
L.r[0] = L.r[i]; //复制为监视哨
j=i-1;
while( L.r[0]<L.r[j])
{
L.r[j+1]=L.r[j]; //记录后移
j--;
}
L.r[j+1] = L.r[0];
}
}
return OK;
}
//***************************************************************
// 二分插入排序
//***************************************************************
Status BInsertSort(Sqlist &L)
{
int i,j,mid,low,high;
if(L.length==0)
{
printf("要排序的数据为空!");
return ERROR;
}
for(i=2;i<=L.length;i++)
{
L.r[0]=L.r[i]; //将L.r[i]暂存在L.r[0]
low=1;
high=i-1; //记录high的初值
while(low<=high) //在r[low..high]中二分查找有序插入的位置
{
mid=(low+high)/2;
if(L.r[0]<L.r[mid]) //插入点在低半区
{
high=mid-1;
}
else
{
low=mid+1;//插入点在高半区
}
}//while
for(j=i-1;j>=low;j--) //插入点后的数据后移
{
L.r[j+1]=L.r[j]; //插入点后的数据后移
}
L.r[low]=L.r[0]; //将数据插入
}//for
return OK;
}
/********************************************************************************
希尔排序
*********************************************************************************/
Status ShellInsert(Sqlist &L,int dk) //希尔插入排序
{
int i,j; //前后位置的增量是dk
for(i=dk+1;i<=L.length;i++) //r[0]只是暂存单元,不是哨兵,
{
if(L.r[i]<L.r[i-dk]) //将L.r[i]插入有序增量子表
{
L.r[0] = L.r[i]; //暂存至L.r[0]
for(j=i-dk;j>0 && L.r[0]<L.r[j];j-=dk)
{
L.r[j+dk]=L.r[j]; //记录后移,查找插入位置
}
L.r[j+dk] = L.r[0]; //插入
}
}
return OK;
}
Status ShellSort(Sqlist &L,int dlta[5],int t) //希尔排序
{
int i;
if(L.length==0)
{
printf("要排序的数据为空!");
return ERROR;
}
for(i=0;i<t;i++)
{
ShellInsert(L,dlta[i]); //一趟增量为dlta[k]的插入排序
}
return OK;
}
//**************************************************************
// 冒泡排序
//**************************************************************
Status BubbleSort(Sqlist &L)
{
int i,j,t;
if(L.length==0)
{
printf("要排序的数据为空!");
return ERROR;
}
for(i=1;i<=L.length-1;i++)
{
for(j=1;j<=L.length-i;j++)
{
if(L.r[j]>L.r[j+1]) //前面的数据>后面数据时
{
t=L.r[j+1];
L.r[j+1]=L.r[j];
L.r[j] = t; //将元素交换
}
}
}
return OK;
}
//****************************************************
// 快速排序
//****************************************************
int Partition(Sqlist &L, int low, int high) //交换顺序表中子表L.r[low..high]的记录,使得枢轴记录到位,并返回其所在位置,此时在它之前(后)的记录均不大于它
{
int pivotkey; //记录关键字
L.r[0] = L.r[low]; //用子表的第一个纪录作枢轴纪录
pivotkey=L.r[low]; //用枢轴纪录关键字
while (low<high)
{
while(low<high && L.r[high]>=pivotkey)
{
high--;
}
L.r[low] = L.r[high]; //将比枢轴记录小的记录移到低端
while(low<high && L.r[low]<=pivotkey)
{
low++;
}
L.r[high] = L.r[low]; //将比枢轴记录大的数移到高端
}
L.r[low]=L.r[0]; //枢轴记录到位
return low;
}//Partition函数
void Qsort (Sqlist &L,int low, int high)
{
int pivotloc;
if (low<high) //长度大于1,可以进行
{
pivotloc=Partition(L, low ,high);
Qsort(L,low,pivotloc-1); //对低子表递归排序,pivotloc是枢轴位置
Qsort(L,pivotloc+1,high); //对高子表递归排序
}
}//Qsort函数
Status QuickSort (Sqlist &L)
{
if(L.length==0)
{
printf("要排序的数据为空!");
return ERROR;
}
Qsort(L,1,L.length);
return OK;
}//QuickSort
//**********************************************
// 简单选择排序
//**********************************************
Status ChooseSort(Sqlist &L)
{
int i,j,min,t;
if(L.length==0)
{
printf("没有数据!");
return ERROR;
}
for(i=1;i<L.length;i++) //排序的趟数
{
min=i;
for(j=i+1;j<L.length;j++) //比较第i个元素以及其后的数据中最小的
{
if(L.r[j]<L.r[min])
min=i;
}
if(i!=min) //将最小数据赋值给L.r[i]
{
t=L.r[i];
L.r[i]=L.r[min];
L.r[min]=t;
}
}
return OK;
}
//**************************************
// 主函数
//**************************************
int main()
{
Sqlist L;
Sqlist L0;
InitSqlist(L); //初始化L
InitSqlist(L0);
int m,i,t;
int dlta[10];
int choice;
//向L中输入元素
printf("\n ************************************************************************\n");
printf(" \n");
printf(" 排序算法 \n");
printf(" \n");
printf(" ***************************************************************************\n");
printf(" 以下是各个排序算法的代号:\n\n");
printf(" 1、直接插入排序 \n");
printf(" 2、二分插入排序 \n");
printf(" 3、希尔排序 \n");
printf(" 4、快速排序\n");
printf(" 5、冒泡排序\n");
printf(" 6、简单选择排序\n");
printf(" 7、退出该系统\n\n");
ScanfSqlist(m,L0); //输入待排序整数
printf("\n");
printf(" 1、直接插入排序 \n");
printf(" 2、二分插入排序 \n");
printf(" 3、希尔排序 \n");
printf(" 4、快速排序\n");
printf(" 5、冒泡排序\n");
printf(" 6、简单选择排序\n");
printf(" 7、退出该系统\n\n");
printf("\n请选择排序的方式,数字1-6: \n");
scanf("%d",&choice); //选择排序方式赋值choice,用于后面的函数选择
while(choice<1||choice>8)
{
printf("输入方式有误。\n请输入1-6选择排序方式,或者选择7退出系统");
scanf("%d",&choice);
}
while(choice!=7)
{
for(i=1;i<=L0.length;i++)
L.r[i]=L0.r[i];
L.length=L0.length;
switch(choice)
{
case 1://直接插入排序
cout<<"完成直接插入排序"<<endl;
InsertSort(L);
break;
case 2://二分插入排序
BInsertSort(L);
cout<<"完成二分插入排序"<<endl;
break;
case 3://希尔排序
cout<<"请输入希尔排序中增量个数:";
cin>>t;
cout<<endl;
cout<<"请依次输入希尔排序中的增量:";
for(i=0;i<t;i++)
cin>>dlta[i];
ShellSort(L,dlta,t);
cout<<"完成希尔排序"<<endl;
break;
case 4://快速排序
QuickSort(L);
cout<<"完成快速排序"<<endl;
break;
case 5://冒泡排序
BubbleSort(L);
cout<<"完成冒泡排序"<<endl;
break;
case 6://简单选择排序
ChooseSort(L);
cout<<"完成简单选择排序"<<endl;
break;
case 7://直接退出
break;
}
PrintfSqlist(m,L); //输出数据和L的长度
printf(" 本次排序结束。\n");
printf(" ___________________________________________________________________\n");
printf(" 继续本系统吗?\n\n");
printf(" 以下是各个排序算法的代号:\n");
printf(" 1、直接插入排序\n");
printf(" 2、二分插入排序\n");
printf(" 3、希尔排序\n");
printf(" 4、快速排序\n");
printf(" 5、冒泡排序\n");
printf(" 6、简单选择排序\n");
printf(" 7、退出该系统\n");
printf("\n请请输入1-6选择排序方式,或者选择7退出系统:");
scanf("%d",&choice);
while(choice<1||choice>7)
{
printf("输入方式有误。\n请输入1-6选择排序方式,或者选择7退出系统");
scanf("%d",&choice);
}
}
return 0;
}