C++ 各种排序算法类
来源:互联网 发布:java的区别和易语言 编辑:程序博客网 时间:2024/06/06 10:00
C++ 各种排序算法类,比如直接插入排序、折半插入排序、Shell排序、归并排序、简单选择排序、基数排序、对data数组中的元素进行希尔排序、冒泡排序、递归实现、堆排序、用数组实现的基数排序等。代码如下:
001
#ifndef SORT_H
002
#define SORT_H
003
#include <iostream>
004
#include <queue>
005
using
namespace
std;
006
// 1.直接插入排序
007
template
<
class
ElemType>
008
void
InsertSort(ElemType data[],
int
n);
009
// 2.折半插入排序
010
template
<
class
ElemType>
011
void
BInsertSort(ElemType data[],
int
n);
012
// 3.Shell排序
013
// 对data数组中的元素进行希尔排序,n为该数组大小
014
// increments为增量序列,incrementsLength为增量序列的大小
015
template
<
class
ElemType>
016
void
ShellSort(ElemType data[],
int
increments[],
int
n,
int
incrementsLength);
017
// 1.Bubble Sort
018
template
<
class
ElemType>
019
void
BubbleSort(ElemType data[],
int
n);
020
// 2.快速排序
021
template
<
class
ElemType>
022
void
QuickSort(ElemType data[],
int
n);
023
//////////////////
024
// Merge Sort
025
//////////////////
026
// 归并排序
027
template
<
class
ElemType>
028
void
MergeSort(ElemType data[],
int
n);
029
template
<
class
ElemType>
030
void
MergeSortNonRecursion(ElemType data[],
int
n);
031
//////////////////
032
// Selection sort
033
//////////////////
034
// 简单选择排序
035
template
<
class
ElemType>
036
void
SelectionSort(ElemType data[],
int
n);
037
// 堆排序
038
template
<
class
ElemType>
039
void
HeapSort(ElemType data[],
int
n);
040
///////////////
041
// Radix Sort
042
///////////////
043
// 静态链表结点
044
const
int
DIGITS = 10;
045
const
int
RADIX = 10;
046
class
SLList;
047
ostream& operator<<(ostream& os, SLList &s);
// 由于VC++6.0使用using namespace std对于友元不支持
048
// 故在类SLList之前做前向声明
049
// 若使用其他C++编译器,这两句可删去
050
// 静态链表static linked list
051
// [0]:头结点
052
class
SLList
053
{
054
struct
Node
055
{
056
int
key[DIGITS];
057
int
info;
058
int
next;
059
};
060
061
friend
ostream& operator<<(ostream& os, SLList &s);
062
public
:
063
SLList():data(NULL),length(0){};
064
~SLList();
065
void
Arrange();
066
void
Init(
int
arr[],
int
n);
067
void
RadixSort();
068
private
:
069
void
Distribute(
int
[],
int
[],
int
);
070
void
Collection(
int
[],
int
[],
int
);
071
Node *data;
072
int
length;
073
};
074
// 基数排序
075
void
RadixSort(
int
data[],
int
n);
076
//void RadixSort(SLList&);
077
///////////////
078
// util
079
///////////////
080
template
<
class
ElemType>
081
void
Swap( ElemType& a, ElemType& b)
082
{
083
ElemType c = a;
084
a = b;
085
b = c;
086
}
087
int
init(
int
** data);
088
template
<
class
ElemType>
089
void
print(ElemType data[],
int
begin,
int
end);
090
// 直接插入排序,数组data用于存放待排序元素,n为待排序元素个数
091
template
<
class
ElemType>
092
void
InsertSort(ElemType data[],
int
n)
093
{
094
ElemType tmp;
095
int
i, j;
096
for
(i = 1; i < n; i++){
097
if
( data[i] > data[i - 1])
098
continue
;
099
tmp = data[i];
// 保存待插入的元素
100
data[i] = data[i - 1];
101
for
( j = i - 1; j > 0 && data[j - 1] > tmp;j--)
102
data[j] = data[j - 1];
// 元素后移
103
data[j] = tmp;
// 插入到正确位置
104
}
105
}
106
// 折半插入排序
107
template
<
class
ElemType>
108
void
BInsertSort(ElemType data[],
int
n)
109
{
110
ElemType tmp;
111
int
i, j, mid, low, high;
112
for
(i = 1; i < n; i++){
113
tmp = data[i];
// 保存待插入的元素
114
low = 0;
115
high = i-1;
116
while
(low <= high){
// 在data[low..high]中折半查找有序插入的位置
117
mid = (low + high) / 2;
// 折半
118
if
( tmp < data[mid])
119
high = --mid;
// 插入点在低半区
120
else
121
low = ++mid;
// 插入点在高半区
122
}
123
for
(j = i - 1; j >= low; j--)
124
data[j + 1] = data[j];
// 元素后移
125
data[low] = tmp;
// 插入到正确位置
126
}
127
}
128
// 对data数组中的元素进行希尔排序,n为该数组大小
129
// increments为增量序列,incrementsLength为增量序列的大小
130
template
<
class
ElemType>
131
void
ShellSort(ElemType data[],
int
increments[],
int
n,
int
incrementsLength)
132
{
133
int
i, j, k;
134
ElemType tmp;
135
for
( k = 0; k < incrementsLength; k++){
// 进行以increments[k]为增量的排序
136
for
( i = increments[k]; i < n; i++){
137
tmp = data[i];
138
for
( j = i; j >= increments[k]; j -= increments[k]){
139
if
( tmp >= data[j - increments[k]])
140
break
;
141
data[j] = data[j - increments[k]];
142
}
143
data[j] = tmp;
144
}
145
}
146
}
147
// 冒泡排序
148
template
<
class
ElemType>
149
void
BubbleSort(ElemType data[],
int
n)
150
{
151
int
lastSwapIndex = n - 1;
// 用于记录最后一次交换的元素下标
152
int
i, j;
153
for
(i = lastSwapIndex; i > 0;i = lastSwapIndex)
154
{
155
lastSwapIndex = 0;
156
for
(j = 0; j < i; j++)
157
if
(data[j] > data[j + 1]){
158
Swap( data[j],data[j + 1]);
159
lastSwapIndex = j;
160
}
161
}
162
}
163
//快速排序
164
template
<
class
ElemType>
165
int
Partition(ElemType data[] ,
int
low ,
int
high)
166
{
167
ElemType pivot = data[low];
168
while
(low < high){
169
while
(low < high && data[high] >= pivot)
170
high--;
171
data[low] = data[high];
172
while
(low < high && pivot >= data[low])
173
low++;
174
data[high] = data[low];
175
}
176
data[low] = pivot;
177
return
low;
178
}
179
template
<
class
ElemType>
180
void
QuickSort(ElemType data[],
int
begin,
int
end)
181
{
182
if
(begin >= end)
183
return
;
184
int
pivot = Partition(data , begin , end);
185
QuickSort(data , begin , pivot - 1);
186
QuickSort(data , pivot + 1, end);
187
}
188
template
<
class
ElemType>
189
void
QuickSort(ElemType data[],
int
n)
190
{
191
if
(n < 2)
192
return
;
193
QuickSort(data, 0, n-1);
194
}
195
// 将数组data中,[lptr...rptr-1][rptr...rightEnd]两部分的元素进行合并
196
// tmpArr为合并时的辅存空间
197
template
<
class
ElemType>
198
void
Merge(ElemType data[], ElemType tmpArr[],
int
lptr,
int
rptr,
int
rightEnd)
199
{
200
int
leftEnd = rptr - 1;
201
int
ptr,i;
202
ptr = i = lptr;
203
while
(lptr <= leftEnd && rptr <= rightEnd)
204
if
(data[lptr] <= data[rptr])
205
tmpArr[ptr++] = data[lptr++];
206
else
207
tmpArr[ptr++] = data[rptr++];
208
while
(lptr <= leftEnd)
209
tmpArr[ptr++] = data[lptr++];
210
while
(rptr <= rightEnd)
211
tmpArr[ptr++] = data[rptr++];
212
for
(;i <= rightEnd; i++)
213
data[i] = tmpArr[i];
214
}
215
// 递归实现
216
// 将数组data中,[begin...end]的元素进行归并排序
217
template
<
class
ElemType>
218
void
MSort(ElemType data[], ElemType tmpArr[],
int
begin,
int
end)
219
{
220
int
middle;
221
if
( begin >= end)
222
return
;
223
middle = (begin + end)/2;
// 将data平分为[begin..middle]和[middle..end]
224
MSort( data, tmpArr, begin, middle);
// 递归前半部分
225
MSort( data, tmpArr, middle + 1, end);
// 递归后半部分
226
Merge( data, tmpArr, begin, middle + 1, end);
// 将data[begin..middle],data[middle..end]进行归并
227
}
228
template
<
class
ElemType>
229
void
MergeSort(ElemType data[],
int
n)
230
{
231
ElemType* pArr = NULL;
232
pArr =
new
ElemType[n];
233
MSort( data,pArr,0,n-1);
234
delete
[] pArr;
235
}
236
// 非递归实现
237
template
<
class
ElemType>
238
void
MPass(ElemType data[], ElemType tmpArr[],
int
n,
int
mergeLength)
239
{
240
int
i = 0;
241
while
(i <= n - 2 * mergeLength){
242
Merge(data, tmpArr, i, i + mergeLength, i + 2 * mergeLength - 1);
243
i = i + 2 * mergeLength;
244
}
245
if
(i + mergeLength < n)
246
Merge(data, tmpArr, i, i + mergeLength, n - 1);
247
}
248
template
<
class
ElemType>
249
void
MergeSortNonRecursion(ElemType data[],
int
n)
250
{
251
int
mergeLength = 1;
252
ElemType* pArr = NULL;
253
pArr =
new
ElemType[n];
254
while
(mergeLength < n){
255
MPass(data, pArr, n, mergeLength);
256
mergeLength *= 2;
257
}
258
delete
[] pArr;
259
}
260
// 简单选择排序
261
template
<
class
ElemType>
262
void
SelectionSort(ElemType data[],
int
n)
263
{
264
int
i, j, min;
265
for
(i = 0; i < n; i++){
266
min = i;
267
for
(j = i + 1; j < n; j++){
268
if
( data[j] < data[min])
269
min = j;
270
}
271
Swap(data[i],data[min]);
272
}
273
}
274
// 堆排序
275
// i为指定元素在数组中的下标
276
// 返回指定结点的左孩子在数组中的下标
277
inline
int
LeftChild(
int
i)
278
{
279
return
2 * i + 1;
280
}
281
template
<
class
ElemType>
282
void
HeapAdjust(ElemType data[],
int
i,
int
n)
283
{
284
ElemType tmp;
285
int
child;
286
for
( tmp = data[i]; LeftChild(i) < n; i = child){
287
child = LeftChild(i);
288
if
(child != n - 1 && data[child + 1] > data[child])
// 取较大的孩子结点
289
child++;
290
if
(tmp < data[child])
291
data[i] = data[child];
292
else
293
break
;
294
}
295
data[i] = tmp;
296
}
297
template
<
class
ElemType>
298
void
HeapSort(ElemType data[],
int
n)
299
{
300
int
i;
301
for
(i = n/2; i >= 0; i--)
// 建堆
302
HeapAdjust(data, i, n);
303
for
(i = n - 1;i > 0; i--){
// 将堆的根结点与最后的一个叶结点交换,并进行调整
304
Swap(data[0],data[i]);
305
HeapAdjust(data, 0, i);
306
}
307
}
308
// 用数组实现的基数排序
309
void
RadixSort(
int
data[],
int
n)
310
{
311
const
int
radix = 10;
312
const
int
digits = 10;
313
int
i,j,k,factor;
314
queue<
int
> queues[radix];
315
for
( i = 0,factor = 1; i < digits;i++,factor *= radix){
316
for
( j = 0;j < n; j++)
317
queues[(data[j]/factor)%radix].push(data[j]);
// 分配
318
for
( k = j = 0; j < radix; j++,k++)
// 收集
319
while
(!queues[j].empty()){
320
data[k] = queues[j].front();
321
queues[j].pop();
322
}
323
}
324
}
325
// 分配
326
void
SLList::Distribute(
int
front[],
int
rear[],
int
digit)
327
{
328
int
i, index;
329
for
(i = 0; i < RADIX; i++)
330
front[i] = 0;
331
for
(i = data[0].next; i > 0; i = data[i].next){
332
index = data[i].key[digit];
333
if
(front[index] == 0)
334
front[index] = i;
335
else
336
data[rear[index]].next = i;
337
rear[index] = i;
338
}
339
}
340
// 收集
341
void
SLList::Collection(
int
front[],
int
rear[],
int
digit)
342
{
343
int
i, current;
344
for
(i = 0; front[i] == 0; i++);
// 找到第一个非空子表
345
data[0].next = front[i];
// 头结点指向第一个非空子表中第一个结点
346
current = rear[i++];
347
for
(; i < RADIX; i++){
348
if
(front[i] == 0)
349
continue
;
350
data[current].next = front[i];
// 链接两个非空子表
351
current = rear[i];
352
}
353
data[current].next = 0;
354
}
355
// 用SLList实现的基数排序
356
void
SLList::RadixSort()
357
{
358
int
i;
359
int
front[RADIX],rear[RADIX];
360
// 从最低位优先依次对各关键字进行分配收集
361
for
( i = 0; i < DIGITS; i++){
362
Distribute(front, rear, i);
363
Collection(front, rear, i);
364
}
365
}
366
SLList::~SLList()
367
{
368
delete
[] data;
369
length = 0;
370
}
371
void
SLList::Init(
int
arr[],
int
n)
372
{
373
length = n + 1;
374
if
(data != NULL)
375
delete
[] data;
376
data =
new
Node[n + 1];
377
data[0].next = 1;
378
for
(
int
i = 1; i <= n; i++){
379
int
value = data[i].info = arr[i - 1];
380
for
(
int
j = 0;j < 10; j++){
381
data[i].key[j] = value % 10;
// + '0';
382
value /= 10;
383
}
384
data[i].next = i + 1;
385
}
386
data[n].next = 0;
387
}
388
// 根据链表中各结点的指针值调整元素位置,使得SLList中元素按关键字正序排列
389
void
SLList::Arrange()
390
{
391
int
i, tmp;
392
int
current = data[0].next;
// current存放第一个元素的当前位置
393
for
(i = 1; i < length; i++){
394
while
(current < i)
// 找到第i个元素,并用current存放其在静态链表中当前位置
395
current = data[current].next;
396
tmp = data[current].next;
397
if
(current != i){
398
Swap(data[current], data[i]);
// 第i个元素调整到位
399
data[i].next = current;
// 指向被移走的元素
400
}
401
current = tmp;
// 为找第i + 1个元素做准备
402
}
403
}
404
ostream& operator<<(ostream& os,SLList &s)
405
{
406
for
(
int
i = 1; i < s.length; i++)
407
cout << s.data[i].info <<
" "
;
408
os << endl;
409
return
os;
410
}
411
#endif
0 0
- 各种排序算法 C语言版
- 各种排序算法--C 转载
- C语言各种排序算法
- 总结各种排序算法(C++)
- C语言各种排序算法
- c/c++各种排序算法
- 各种排序算法的C实现
- 各种排序算法的C实现(转载)
- 各种排序算法总结(C语言)
- C语言各种排序算法汇总
- 各种排序算法源码(c++)20150913
- C语言实现各种排序算法
- 各种排序算法总结(Python,C++)
- C++ 各种排序算法类
- C++ 各种排序算法类
- c语言实现各种排序算法(作业:点名册排序)
- 【算法】各种排序算法
- C语言版各种排序算法(持续更新中)
- 无法解析的外部符号
- JVM详解
- Oracle SQL的硬解析和软解析
- sap 长文本的读取
- windows配置svn自动启动
- C++ 各种排序算法类
- 文件读写函数
- 输入若干数字计算数字之和的程序
- bash中的if语法
- 算法学习
- C通过unixODBC连接数据库
- Mina框架学习笔记(四)
- acdream 1105(dfs)
- ContextLoaderListener作用详解