#define _CRT_SECURE_NO_WARNINGS 1
#include"Sort.h"
void Swap(int* a, int* b)
{
int tmp = *a;
*a = *b;
*b = tmp;
}
void InsertSort(int* a, int n)
{
assert(a);
int i = 0;
int j = 0;
for (i = 0; i < n - 1; i++)
{
int end = i;
int tmp = a[end + 1];
while (end >= 0)
{
if (tmp < a[end])
{
a[end + 1] = a[end];
end--;
}
else
{
break;
}
}
a[end + 1] = tmp;
}
}
void ShellSort(int* a, int n)
{
int gap = 3;
int j = 0;
int i = 0;
while (gap > 1)
{
gap =gap / 3 + 1;//gap不等于1的时候是在预排序
for (i = 0; i < n - gap; i++)
{
int end = i;
int tmp = a[end + gap];
while (end >= 0)
{
if (tmp > a[end])
{
a[end + gap] = a[end];
end -= gap;
}
else
{
break;
}
}
a[end + gap] = tmp;
}
}
}
void SelectSort(int* a, int n)
{
int left = 0;
int right = n;
while (left < right)
{
int max = left;
int min = left;
for (int i = left; i < right; i++)
{
if (a[i] > a[max])
{
max = i;
}
else if (a[i] < a[min])
{
min = i;
}
}
Swap(&a[left], &a[min]);
//如果left和max 相等 那么由于之前left位置的数和min位置互换 所以应该把max的值更正为min
if (left == max)
{
max = min;
}
Swap(&a[right - 1], &a[max]);
left++;
right--;
}
}
void AdjustDown(HPDataType* a, int n, int parent)
{
int child = 2 * parent + 1;
while (child < n)
{
if (a[child] > a[child + 1] && child + 1 < n)
{
child += 1;
}
if (a[child] < a[parent])
{
Swap(&a[child], &a[parent]);
parent = child;
child = 2 * parent + 1;
}
else
{
break;
}
}
}
void HeapSort(HPDataType* a, int n)//O(N*logN)
{
//建堆
//向下建堆O(N*logN)
/*int i = 0;
for (i = 0; i < n; i++)
{
AdjustUp(a, n, i);
}*/
//向上建堆O(N)
for (int i = (n - 1 - 1) / 2; i >= 0; i--)
{
AdjustDown(a, n, i);
}
//排升序用大堆,排降序用小堆
int end = n - 1;
while (end)
{
Swap(&a[0], &a[end]);
end--;
AdjustDown(a, end, 0);
}
}
int GetMid(int* a, int left, int right)
{
int mid = (left + right) / 2;
if (a[left] > a[right])
{
if (a[right] > a[mid])
{
return right;
}
else if (a[mid] > a[left])
{
return left;
}
else
{
return mid;
}
}
else//a[left] < a[right]
{
if (a[right] < a[mid])
{
return right;
}
else if (a[left] > a[mid])
{
return left;
}
else
{
return mid;
}
}
}
void QuickSort(int a[], int left, int right)//闭区间
{
1.Hoare法//选取最左或最后作为key值,在从所选的对向开始找小于key数(升序),从key方向开始找大于key的数交换,直到相遇
//if (left >= right)
//{
// return;
//}
//int key = left;
//int end = right;
//int begin = left;
//while (left < right)
//{
// while (left < right && a[right] >= a[key])
// {
// right--;
// }
// while (left < right && a[left] <= a[key])
// {
// left++;
// }
// Swap(&a[left], &a[right]);
//}
//Swap(&a[key], &a[right]);
//key = right;
//QuickSort(a, begin, key - 1);
//QuickSort(a, key + 1,end);
//2.挖坑法//先将第一个数据放到一个临时变量中,形成一个坑位
/*if (left >= right)
{
return;
}
int pit = left;
int key = a[left];
int begin = left;
int end = right;
while (left < right)
{
while (left < right && a[right] >= key)
{
right--;
}
a[pit] = a[right];
pit = right;
while (left < right && a[left] <= key)
{
left++;
}
a[pit] = a[left];
pit = left;
}
a[pit] = key;
QuickSort(a, begin, pit - 1);
QuickSort(a, pit + 1, end);*/
//前后指针法 以左边第一个值为key值 prev在第一个位置 cur在第二个位置
//cur先走如果遇到比key小的数的时候就和prev前面的数交换 因为prev指的是比key小的数
//他的前一个数cur走过是大于key的交换后 prev更新位置
if (left >= right)
{
return;
}
/*Swap(&a[prev], &a[left]);
QuickSort(a, left, prev);
QuickSort(a, prev + 1, right);*/
if (right - left > 15)//如果数据量大于15 那么就采用递归
{
int prev = left;
int cur = prev + 1;
//三数取中优化
Swap(&a[left], &a[GetMid(a, left, right)]);
int key = a[left];
while (cur <= right)
{
if (a[cur] < key && prev++ != cur)
{
Swap(&a[cur], &a[prev]);
}
cur++;
}
Swap(&a[prev], &a[left]);
QuickSort(a, left, prev - 1);
QuickSort(a, prev + 1, right);
}
else// 小于15 就采用插排减少递归次数
{
//swap(&a[prev], &a[left]);
InsertSort(a + left, right - left + 1);
}
}
void QuickSortNoR(int a[], int left, int right)//非递归快排
{
Stack* st = (Stack*)malloc(sizeof(Stack));
StackInit(st);
StackPush(st, right);
StackPush(st, left);
while (!StackEmpty(st))
{
int begin = StackTop(st);
StackPop(st);
int prev = begin;
int end = StackTop(st);
StackPop(st);
int cur = prev + 1;
//三数取中优化
Swap(&a[begin], &a[GetMid(a, begin, end)]);
int key = a[begin];
while (cur <= end)
{
if (a[cur] < key && prev++ != cur)
{
Swap(&a[cur], &a[prev]);
}
cur++;
}
Swap(&a[prev], &a[begin]);
if (end > prev + 1)
{
StackPush(st, end);
StackPush(st, prev + 1);
}
if (begin < prev - 1)
{
StackPush(st, prev);
StackPush(st, begin);
}
}
}
void _MergeSort(int* a, int begin , int end, int* tmp)
{
if (begin >= end)//如果空间中只有一个数或者空间不存在就返回
{
return;
}
int mid = (begin + end) / 2;
_MergeSort(a, begin, mid, tmp);
_MergeSort(a, mid + 1, end, tmp);//产生待排序的两段空间
//归并
int begin1 = begin;
int end1 = mid;
int begin2 = mid + 1;
int end2 = end;
int i = begin;
while (begin1 <= end1 && begin2 <= end2)
{
if (a[begin1] < a[begin2])
{
tmp[i++] = a[begin1++];
}
else
{
tmp[i++] = a[begin2++];
}
}
while (begin1 <= end1)
{
tmp[i++] = a[begin1++];
}
while (begin2 <= end2)
{
tmp[i++] = a[begin2++];
}
memcpy(a + begin, tmp + begin, (end - begin + 1)*sizeof(int));
}
void MergeSort(int* a, int n)
{
int* tmp = (int*)malloc(n * sizeof(int));
_MergeSort(a, 0, n - 1,tmp);
free(tmp);
}
void MergeSortNoR(int* a, int n)// 归并非递归
{
int* tmp = (int*)malloc(sizeof(int) * n);
int gap = 1;
while (gap < n)
{
//printf("gap = %d->", gap);
for (int j = 0; j < n; j += 2 * gap)
{
//[begin][begin + gap -1],[begin + gap][begin + 2*gap -1]
int begin1 = j;
int end1 = begin1 + gap - 1;
int begin2 = begin1 + gap;
int end2 = begin2 + gap - 1;
int i = begin1;
int left = begin1;
int right = end2;
// 判断越界问题
if (end1 >= n)// end1 越界
{
end1 = n - 1;
begin2 = n;
end2 = n - 1;
}
else if (begin2 >= n)// begin2越界
{
begin2 = n;
end2 = n - 1;
}
else if (end2 >= n)// end2越界
{
end2 = n - 1;
}
//printf("[%d][%d] [%d][%d]--", begin1, end1, begin2, end2);
while (begin1 <= end1 && begin2 <= end2)
{
if (a[begin1] < a[begin2])
{
tmp[i++] = a[begin1++];
}
else
{
tmp[i++] = a[begin2++];
}
}
while (begin1 <= end1)
{
tmp[i++] = a[begin1++];
}
while (begin2 <= end2)
{
tmp[i++] = a[begin2++];
}
memcpy(a + left, tmp + left, (right - left + 1) * sizeof(int));
}
//printf("\n");
gap *= 2;
}
}
void BubbleSort(int* a, int n)
{
for (int i = 0; i < n - 1; i++)
{
int flag = 1;
for (int j = n - 1; j > i; j--)
{
if (a[j] < a[j - 1])
{
Swap(&a[j], &a[j - 1]);
flag = 0;
}
}
if (flag)
{
break;
}
flag = 1;
}
}
void CountSort(int* a, int n)
{
int min = a[0], max = a[0];
for (int i = 0; i < n; i++)
{
if (a[i] < min)
{
min = a[i];
}
if (a[i] > max)
{
max = a[i];
}
}
int range = max - min + 1;
int* count = (int*)malloc(sizeof(int) * range);
memset(count, 0, sizeof(int) * range);
for (int j = 0; j < n; j++)
{
count[a[j] - min]++;
}
int i = 0;
for (int j = 0; j < range; j++)
{
while (count[j]--)
{
a[i++] = j + min;
}
}
}