#pragma once//函数文件
#include<iostream>
#include<assert.h>
using namespace std;
void InsertSort(int* a,size_t size)
{
assert(a);
size_t i = 0;
for (; i < size - 1; ++i)
{
int end = i;
int next = i+1;
while (end>=0)
{
if (a[end]>a[next])
{
swap(a[end], a[next]);
next = end;
}
--end;
}
}
}
void ShellSort(int* a, size_t size)//希尔排序
{
assert(a);
size_t i = 0;
size_t gap = size;//gap 为 插入间隔
while (gap > 1)//间隔不为1 循环
{
gap = gap / 3 + 1;
for (i=0; i < size - gap; ++i) //从1 位起 依次插入 之前有序的序列
{
int end = i; //end表示有序序列末尾
size_t next = i + gap;//第一个要插入的为末尾加间隔
while (end >= 0&&next<size)
{
if (a[end]>a[next])
{
swap(a[end], a[next]);
next = end;
}
end-=gap;
}
}
}
}
void QuickSort( int* a,int left,int right)//快慢指针的快排
{
assert(a);
if (left >= right)
return;
int key = a[left];
int start = left;
int end = right;
while (end>start)
{
if (a[end] < key)
++start;
else
--end;
if (a[end]< key&&a[start] > key)
swap(a[end],a[start]);
}
if (a[left] > a[start])
swap(a[left], a[start]);
QuickSort(a, left, start - 1);
QuickSort(a, start+1, right);
}
void QuickSort_PC(int* a,size_t left,size_t right)//前后指针快排
{
assert(a);
size_t prev=left;
size_t cur =left;
size_t key = left;
for (; cur<=right;)
{
if (a[cur] < a[key]&&prev<cur)
{
if (a[prev]>a[key])
swap(a[cur], a[prev]);
else
++prev;
}
else
++cur;
}
if (a[prev] < a[key])
swap(a[prev], a[key]);
if (left < right)
{
QuickSort_PC(a, left, prev);
QuickSort_PC(a, prev+1, right);
}
}
int MaxDigit(int *a, size_t size)
{
int count = 1;
int max = 10;
for (size_t i = 0; i < size; ++i)
{
while(a[i] >= max)
{
max *= 10;
++count;
}
}
return count;
}
//基数排序 只能正整数(利用数组下标特性)
void RadixSort(int * a,size_t size)
{
assert(a);
int* count = new int[10]; //生成每一位 的值得数组0--9 计数
int* bucket = new int[size]; //生成储存排过一次序后的元素 数组
int maxDigit = MaxDigit(a, size);//计算最大数 位数
int digit = 1;//循环计数变量
while (maxDigit >=digit ) //从个位到最高位 排序次数
{
for (size_t i = 0; i < size; ++i)
{
bucket[i] = 0; //将数组制零
}
for (int i = 0; i < 10; ++i)
{
count[i] = 0;//将桶的计数 制零
}
for (size_t i = 0; i < size; ++i)
{
int j = (a[i] / (int)pow(10, digit - 1)) % 10;//计算每一位的值
++count[j];//计数自加
}
for (size_t i = 1; i <10; ++i)
{
count[i] = count[i] + count[i - 1];//计算根据每一位排序后第一个元素 在bucket[]中的起始位置
}
int index=0; //计算下标
int k = 0; //当某位 为0时,下标的计数
for (size_t i = 0; i <size; ++i)
{
index = (a[i] / (int)pow(10, digit - 1)) % 10;
if (index == 0)
bucket[k++] = a[i];
else
bucket[count[index-1]++]=a[i];//某位 数值不为0,第一个元素位置count[下标-1]
}
memmove(a, bucket, size*sizeof(int)); //将排过序的数组 拷贝进 原数组
++digit; //计数器自加
}
}
void PartitionMerger(int* dst, int* src , size_t start, size_t mid, size_t end)
{//
size_t i = start, j = mid+1, k = start;//mid指向后半区间第一个
for (; i <=mid&&j <=end;)//按大小依次将src中区间内数据写去dst
{
if (src[i]>src[j])
{
dst[k] = src[j];
++j;
}
else
{
dst[k] = src[i];
++i;
}
++k;
}
while (i <=mid) //剩下的继续写去
{
dst[k] = src[i];
++i;
++k;
}
while (j <=end)
{
dst[k] = src[j];
++j;
++k;
}
memmove(src+start, dst+start, (end - start+1)*4);//将一归并排序区间内的数据写入src src为临时数组
}
void mergerSort(int* dst,int* src,size_t start,size_t end)
{
size_t mid = start + (end - start) / 2;
if (end-start>1)//区间个数大于2 分小区间
{
mergerSort(dst,src,start,mid);
mergerSort(dst,src,mid+1,end);
}
PartitionMerger(dst, src, start, mid, end);//单趟排序
}
void MergerSort(int* a, size_t start, size_t end)//封装 归并排序
{
assert(a);
int* tmp = new int[end - start + 1];//储存区间归并排序的结果
mergerSort( tmp,a , start, end);//归并排序
delete tmp;
}
void Print(int* a,size_t size)
{
for (size_t i = 0; i < size; ++i)
{
cout << a[i] << ' ';
}
cout << endl;
}
//主函数 测试用例
#include"allsort.hpp"
void test()
{
int a[10] = { 5, 9, 6, 4, 7, 8, 3, 1, 2, 0 };
InsertSort(a, 10);
Print(a, 10);
}
void test1()
{
int a[10] = { 5, 9, 6, 4, 7, 8, 3, 1, 2, 0 };
ShellSort(a, 10);
Print(a, 10);
}
void test2()
{
int a[13] = { 5, 9, 6,5,1,2, 4, 7, 8, 3, 1, 2, 0 };
QuickSort(a, 0,12);
Print(a, 13);
}
void test3()
{
int a[13] = { 5, 9, 6, 5, 1, 2, 4, 7, 8, 3, 1, 2, 0 };
QuickSort_PC(a, 0, 12);
Print(a, 13);
}
void test4()
{
int a[17] = { 15, 39, 26,35, 51, 42, 44, 77, 68, 43, 51, 82, 90 ,100,999,1001,199563};
RadixSort(a, 17);
Print(a, 17);
}
void test5()
{
int a[11] = { 1, 9, 6, 5, 1, 2, 4, 7, 8, 3, 3 };
MergerSort(a, 0, 10);
Print(a, 11);
}
int main()
{
test();
test1();
test2();
test3();
test4();
test5();
return 0;
}
转载于:https://blog.51cto.com/shaungqiran/1757686