(一)直接插入排序
直接插入排序的思想是从下下标为1的数开始每遍历一个数,就往前比较直到插入合适的位置下面画图说明
# include<iostream>
# include<cassert>using namespace std;
size_t *InsertSort1(size_t *array, size_t size)//直接插入排序双循环写法
{
assert(array);
for (int i = 1; i < size; i++)
{
size_t temp = array[i];
int j = i - 1;
for (; j >= 0 && temp<array[j]; j--)//查找合适的插入位置
{
array[j + 1] = array[j];//往后挪动
}
array[j+1] = temp;//找到合适的插入位置
}
return array;
}
size_t* InsertSort2(size_t *array, size_t size)//直接插入排序while循环写法
{
assert(array);
for (size_t i = 1; i < size; i++)
{
size_t index = i;
size_t temp = array[index];
size_t end = index - 1;
while (end>0 && temp < array[end])
{
array[end + 1] = array[end];
end--;
}
array[end+1] = temp;
}
return array;
}
//(二)希尔排序
size_t *ShellSort(size_t *array, size_t size)//希尔排序{
assert(array);
int gap = size;
while (gap > 1)
{
gap = gap / 3 + 1;//定义一个间距
for (int i = 0; i < size; i++)//将gap换成1就是直接排序的部分
{
int index = i;
int temp = array[index];
int end = index - gap;
while (end>0 && temp < array[end])
{
array[end + gap] = array[end];
end -= gap;
}
array[end + gap] = temp;
}
}
return array;
}
void Print(size_t *array, size_t size)
{
for (size_t i = 0; i < size; i++)
{
cout << array[i] << " ";
}
cout << endl;
}
(三)堆排序
void AdjustDown(size_t *array, size_t size, int root)//向下调整堆{
assert(array);
int parent = root;
int child = root * 2 + 1;
while (child < size)
{
if (child + 1 < size&&array[child] < array[child + 1])//这里要建大堆,使堆顶元素成为最大值
{
child++;
}
if (array[child]>array[parent])
{
swap(array[child], array[parent]);
parent = child;
child = child * 2 + 1;
}
else
{
break;
}
}
}
//
size_t *HeapSort(size_t*array, size_t size)//堆排序{
assert(array);
for (int i = (size - 2) / 2; i >= 0; --i)//对所给的完全二叉树建一个大顶堆
{
AdjustDown(array, size, i);
}
for (int i = size - 1; i > 0; --i)//每次将堆顶元素和最后一个元素交换,缩小size的范围
{
swap(array[0], array[i]); //然后从a[0]开始向下调整即可,这样又能将最大的元素调整到a[0]
AdjustDown(array, i, 0); //的位置,如此反复便将所有的元素升序排列
}
return array;
}
(四)冒泡排序
size_t *BubleSort(size_t*array, size_t size)//冒泡排序{
assert(array);
for(int i = 0; i < size; i++)
{
for (int j = size - 1; j > i; j--)//注意边界条件
{
if (array[j] < array[j - 1])
{
swap(array[j], array[j - 1]);
}
}
}
return array;
}
size_t * SelectionSort(size_t *array, size_t size)//选择排序从,后面的无序区依次选出最小的数和
{
assert(array); //前面[0 size)分别交换用一个min记录最小的下标。
for (int i = 0; i < size-1; i++)
{
int min = i;
for (int j = i+1; j<size; j++)
{
if (array[min] > array[j])
{
min = j;
}
}
swap(array[i],array[min]);
}
return array;
}
int main()
{
size_t array[10] = { 98, 5, 2, 78, 12, 21, 55, 12, 15, 1 };
size_t size = 10;
/*size_t *p1=InsertSort1(array, 10);
Print(p1, 10);
size_t *p2=InsertSort2(array, 10);
Print(p2, 10);
size_t *p3 = ShellSort(array, 10);
Print(p3, 10);
size_t *p4 = HeapSort(array, 10);
Print(p4, 10);*/
//size_t *p5 = BubleSort(array, 10);
//Print(p5, 10);
//size_t *p6 = SelectionSort(array, 10);
//Print(p6, 10);
}
(五)快速排序和归并排序
# include<iostream>
# include<cassert>
# include<stack>
using namespace std;
int ThreeGetKey(int *a, int left, int right)//三数取中法的优化key
{
int mid = left + (right - left) / 2;
if (a[left] < a[right])
{
if (a[mid] < a[left])
{
return a[left];
}
else if (a[mid] < a[right])
{
return a[mid];
}
else
{
return a[right];
}
}
else{
if (a[mid] < a[right])
{
return a[right];
}
else if (a[mid] < a[left])
{
return a[mid];
}
else
{
return a[left];
}
}
}
int PartionSort1(int *a, int left, int right)//快速排序部分排序版本1
{
int begin = left;
int end = right;
int key = ThreeGetKey(a, left, right);//优化后,不优化为a[right];
while (begin < end)
{
while (a[begin]<= key&&begin < end)//这两个while循环的先后顺序一定不能交换
{
++begin;
}
while (a[end] >= key&&begin < end)
{
end--;
}
if (begin < end)
{
swap(a[begin], a[end]);
}
}
if (a[begin]>key)
{
swap(a[begin], a[right]);
return begin;
}
else
{
return right;
}
}
int PartionSort2(int *a, int left, int right)//快速排序部分排序版本2
{
int key = a[right];
int cur = left;
int prev = left - 1;
while (cur < right)
{
if (a[cur] < key && ++prev != cur)//cur一直向后走,只要这个值比key小
//(说明前面prev所指的值都是比key大的值)prev就向后走一步,
//若prev和cur不相等就交换
{
swap(a[cur], a[prev]);
}
cur++;
}
swap(a[++prev], a[right]);
return prev;
}
void QuckSort2(int *a, int left, int right)//快速排序的非递归方法
{
if (left < right)
{
stack<int> s;
s.push(right);
s.push(left);
while(!s.empty())
{
int _left = s.top();
s.pop();
int _right = s.top();
int boundary = PartionSort1(a, _left, _right);
s.pop();
if (_left < boundary - 1)
{
s.push(boundary - 1);
s.push(_left);
}
if (boundary + 1 < _right)
{
s.push(_right);
s.push(boundary + 1);
}
}
}
else
{
return;
}
}
void QuckSort(int *a,int left,int right)//快速排序
{
if (left < right)
{
int boundary = PartionSort1(a, left, right);//调用了优化后的部分排序
QuckSort(a, left, boundary-1);//这里一定要是boundary-1,否则会出现死循环
QuckSort(a, boundary + 1, right);
}
}
void MergeSection(int *a, int*tmp, int begin1, int end1, int begin2, int end2)
{
int index = begin1;//这不能是0
while (begin1 <= end1&&begin2 <= end2)
{
if(a[begin1] < a[begin2])
{
tmp[index++] = a[begin1++];
}
else
{
tmp[index++] = a[begin2++];
}
}
while (begin1 <=end1)
{
tmp[index++] = a[begin1++];
}
while (begin2 <= end2)
{
tmp[index++] = a[begin2++];
}
}
void _MergeSort(int *a,int *tmp ,int left, int right)
{
if (left < right)
{
int boundary = left + (right - left) / 2;
_MergeSort(a, tmp, left, boundary);
_MergeSort(a, tmp, boundary + 1, right);
MergeSection(a, tmp, left, boundary, boundary + 1, right);
memcpy(a + left, tmp + left, (right - left + 1)*sizeof(int));//right-left+1
}
}
void MergeSort(int *a, int size)//归并排序
{
int left = 0;
int right = size - 1;
int* tmp = new int[size];
_MergeSort(a,tmp, left, right);
delete[] tmp;
}
void Print(int *a,int size)
{
for (int i = 0; i <= size; i++)
{
cout << a[i] << " ";
}
cout << endl;
}
void CountSort(int *a, size_t size)//计数排序,思想是将对应元素作为辅助矩阵的下标,在辅助矩阵中计算它的个数
{
assert(a); //然后再将它拷回原来的矩阵中去
int Max = a[0];
int Min = a[0];
for (size_t i = 1; i < size; ++i)
{
if (a[i]>Max)
{
Max = a[i];
}
else if (a[i] < Min)
{
Min = a[i];
}
}
int range = Max - Min + 1;
int *CountArray = new int[range];
memset(CountArray, 0, sizeof(int)*range);
for (size_t i = 0; i < size; i++)
{
CountArray[a[i] - Min]++;//有一个相对的偏移量,这样最小值将存在0的位置
}
size_t index = 0;
for (size_t i = 0; i < range; ++i)
{
while (CountArray[i]-->0)
{
a[index++] = Min + i;
}
}
delete[] CountArray;
}
int GetMaxDigit(int *a, size_t size)
{
int digit = 1;//默认值为一位
int Max = 10;
for (size_t i = 0; i < size; i++)
{
while (a[i] >= Max)
{
++digit;
Max *= 10;
}
}
return digit;
}
void DigitSortLSD(int *a, size_t size)
{
assert(a);
int MaxDigit = GetMaxDigit(a, size);
int *bucket = new int[size];
int count[10];
int start[10];
int digit = 1;
int bit = 1;
while (digit <= MaxDigit)
{
memset(count, 0, sizeof(int)* 10);
memset(start, 0, sizeof(int)* 10);
for (size_t i = 0; i < size; ++i)//统计0-9号桶有多少数字
{
int num = (a[i]) % 10;
count[num]++;
}
start[0] = 0;
for (size_t i = 0; i < size; ++i)
{
start[i] = start[i - 1] + count[i - 1];//当前桶的起始位置为前一个桶的起始位置
//加上前一个桶的计数个数;
}
for (size_t i = 0; i < size; ++i)
{
int num = (a[i] / bit) % 10;
bucket[start[num]] = a[i];
}
memcpy(a, bucket, sizeof(int)* 10);
bit = bit * 10;
++digit;
}
}
int main()
{
int a[10] = { 1, 45, 23, 21, 48, 34, 33, 23, 40, 30 };
Print(a, 9);
//QuckSort2(a, 0, 9);
//MergeSort(a, 10);
//CountSort(a, 10);
DigitSortLSD(a, 10);
Print(a, 9);
}