//小区间优化 —— 利用其他排序去优化归并排序 快速排序 降低归并排序和快速排序的递归深度
//快排优化三路
后面文章会更新
比较复杂的我之前已经出过单独的文章了 这里就不再阐述
排序的算法实现 后面的代码是辅助非递归 也就是模拟递归栈的实现
#define _CRT_SECURE_NO_WARNINGS 1
#include"Stack_Queue.h"
void Swap(int* p1, int* p2)
{
int tmp = *p1;
*p1 = *p2;
*p2 = tmp;
}
void InsertSort(int* arr, int sz)
{
for (int i = 0; i < sz - 1; i++)
{
for (int j = i + 1; j >= 1; j--)
{
if (arr[j] < arr[j - 1])
{
Swap(&arr[j], &arr[j - 1]);
}
else
{
break;//将该元素安排到合适的位置之后就没必要再进行循环
}
}
}
}
void Print(int* arr, int sz)
{
for (int i = 0; i < sz; i++)
{
printf("%d ", arr[i]);
}
printf("\n");
}
//希尔排序
//void ShellSort(int* arr, int sz)//一组一组进行排序
//{
// int gap = sz;
// while (gap>1)
// {
// gap = gap / 3 + 1;
// for (int i = 0;i=gap; j-=gap)
// {
// if (arr[j] < arr[j - gap])
// {
// Swap(&arr[j], &arr[j - gap]);
// }
// else
// {
// break;
// }
// }
// }
// }
//}
//void ShellSort(int* arr, int sz)//多组进行排序
//{
// int gap = sz;
// while (gap > 1)
// {
// gap = gap / 3 + 1;
// for (int i = 0; i < sz-gap; i ++)
// {
// for (int j = i; j >= 0; j -= gap)
// {
// if (arr[j] > arr[j + gap])
// {
// Swap(&arr[j], &arr[j + gap]);
// }
// else
// {
// break;
// }
// }
// }
// }
//}
void ShellSort(int* arr, int sz)//多组进行排序
{
int gap = sz;
while (gap > 1)
{
gap = gap / 3 + 1;
for (int i = 0; i < sz-gap; i++)
{
for (int j = i+gap; j >= gap; j -= gap)
{
if (arr[j] < arr[j - gap])
{
Swap(&arr[j], &arr[j - gap]);
}
else
{
break;
}
}
}
}
}
//选择排序 单趟
//void SelectSort(int* arr, int sz)
//{
// //定义一个min
// for (int i = 0; i < sz; i++)
// {
// //int min = arr[i];
// for (int j = i + 1; j < sz; j++)
// {
// //if (min > arr[j])
// if(arr[i] > arr[j])
// {
// Swap(&arr[i], &arr[j]);
// }
// }
// }
//}
//选择排序多趟进行
void SelectSort(int* arr, int sz)
{
int left = 0, right = sz - 1;
while (left <= right)
{
int min = left;
int max = left;
for (int i = left; i <= right; i++)
{
if (arr[i] < arr[min])
{
min = i;
}
if (arr[i] > arr[max])
{
max = i;
}
}
Swap(&arr[left], &arr[min]);
if (max == left)//特殊情况特殊处理 当一组数据中最大值出现在该数据的最左端 就会引起该情况
{
max = min;
}
Swap(&arr[max], &arr[right]);
left++;
right--;
}
}
//堆排序
//向上调整建堆
void AdjustUp(int* arr, int sz)
{
int children = sz;
int parent = (children - 1) / 2;
while (children >= 0)
{
if (arr[parent] < arr[children])
{
Swap(&arr[parent], &arr[children]);
children = parent;
parent = (children - 1) / 2;
}
else
{
break;
}
}
}
//向下调整 建堆
void AdjustDown1(int* arr, int i,int sz)
{
int parent = i;
int children = 2 * parent + 1;
while (children < sz)
{
if (children + 1 < sz && arr[children] > arr[children + 1])
{
children++;
}
if (arr[parent] > arr[children])
{
Swap(&arr[parent], &arr[children]);
parent = children;
children = 2 * parent + 1;
}
else
{
break;
}
}
}
//向下调整不建堆
void AdjustDown(int* arr, int sz)
{
int parent = 0;
int children = 2 * parent + 1;
while (children < sz)
{
if (children + 1 < sz && arr[children] < arr[children + 1])
{
children++;
}
if (arr[parent] < arr[children])
{
Swap(&arr[parent], &arr[children]);
}
else
{
break;
}
parent = children;
children = 2 * parent + 1;
}
}
void HeapSort(int* arr, int sz)
{
//建堆
//向上调整建堆
for (int i = 0; i < sz; i++)
{
AdjustUp(arr, i);//建的是小堆
}
//向下调整建堆
/*for (int i = (sz-1-1)/2; i >= 0; i--)//建立的小堆
{
AdjustDown1(arr, i,sz);
}*/
for (int i = sz - 1; i > 0; i--)
{
Swap(&arr[0], &arr[i]);
AdjustDown(arr,i-1);
}
}
//三数取中
int ThreeNumsMid(int* arr, int left, int right)
{
int mid = (right - left) + left;
if (arr[left] < arr[right])
{
if (arr[left] < arr[mid])
{
return mid;
}
else if(arr[arr[right]=arr[right]
{
if (arr[left] > arr[mid])
{
return mid;
}
else if (arr[mid] > arr[left])
{
return left;
}
else
{
return right;
}
}
}
//快速排序
//Hoare版本 起始版本
void _QuickSort1(int* arr, int left, int right)
{
if (left >= right)
{
return;
}
int begin = left, end = right;
int key = arr[left];
while (begin < end)
{
while (begin < end && arr[end] >= key)
{
end--;
}
while (begin < end && arr[begin] <= key)
{
begin++;
}
Swap(&arr[begin], &arr[end]);
}
Swap(&arr[left], &arr[begin]);
int keyi = begin;
_QuickSort1(arr, left, keyi - 1);
_QuickSort1(arr, keyi + 1, right);
}
//快速排序挖坑版本
void _QuickSort2(int* arr, int left,int right)
{
if (left >= right)
{
return;
}
int begin = left, end = right;
int key = arr[begin];
int keyi = left;
while (begin < end)
{
while (begin < end && key <= arr[end])
{
end--;
}
arr[begin] = arr[end];
while (begin < end && key >= arr[begin])
{
begin++;
}
arr[end] = arr[begin];
}
arr[begin] = key;
_QuickSort2(arr, left, begin - 1);
_QuickSort2(arr, begin + 1, right);
}
//前后指针法
void _QuickSort3(int* arr, int left, int right)
{
if (left >= right)
{
return;
}
int cur = left + 1, prev = left + 1;
int key = arr[left];
while (prev <= right)
{
if (arr[prev] >= key)
{
prev++;
}
else
{
Swap(&arr[prev], &arr[cur]);
prev++;
cur++;
}
}
Swap(&arr[left], &arr[cur-1]);
int keyi = cur - 1;
_QuickSort3(arr, left, keyi - 1);
_QuickSort3(arr, keyi + 1, right);
}
void QuickSort(int* arr, int sz)
{
//_QuickSort1(arr, 0, sz - 1);//Hoare
//_QuickSort2(arr, 0, sz - 1);//挖坑法
_QuickSort3(arr, 0, sz - 1);//前后指针
}
void _MergeSort(int* arr, int left, int right,int* tmp)
{
if (left >= right)
{
return;
}
int mid = (right - left) / 2 + left;
_MergeSort(arr, left, mid,tmp);
_MergeSort(arr, mid + 1, right,tmp);
int i = left;
int begin1 = left, end1 = mid;
int begin2 = mid + 1, end2 = right;
while (begin1 <= end1 && begin2 <= end2)
{
if (arr[begin1] <= arr[begin2])
{
tmp[i++] = arr[begin1++];
}
else
{
tmp[i++] = arr[begin2++];
}
}
while (begin1 <= end1)
{
tmp[i++] = arr[begin1++];
}
while (begin2 <= end2)
{
tmp[i++] = arr[begin2++];
}
int j = 0;
for (j = left; j <= right; j++)
arr[j] = tmp[j];
}
//归并排序
void MergeSort(int* arr, int sz)
{
int* tmp = (int*)malloc(sizeof(int) * sz);
_MergeSort(arr, 0, sz - 1,tmp);
free(tmp);
tmp = NULL;
}
//Hoare版本非递归
int _QuickSortNonR1(int* arr, int left, int right)
{
if (left >= right)return-1;
int begin = left, end = right;
while (begin < end)
{
while (begin < end && arr[end] >= arr[left])
end--;
while (begin < end && arr[begin] <= arr[left])
begin++;
Swap(&arr[end], &arr[begin]);
}
Swap(&arr[left], &arr[begin]);
return begin;
}
//挖坑法非递归版本
int _QuickSortNonR2(int* arr, int left, int right)
{
if (left >= right)return -1;
int begin = left, end = right;
int tmp = arr[left];
while (begin < end)
{
while (begin < end && arr[end] >= tmp)
end--;
arr[begin] = arr[end];
while (begin < end && arr[begin] <= tmp)
begin++;
arr[end] = arr[begin];
}
arr[begin] = tmp;
return begin;
}
//前后指针法非递归版本
int _QuickSortNonR3(int* arr, int left, int right)
{
if (left >= right)return-1;
int cur = 0, prev = 1;
while (prev <= right)
{
if (arr[prev] < arr[left])
{
prev++;
}
else
{
prev++;
cur++;
Swap(&arr[cur], &arr[prev]);
}
}
return cur;
}
//非递归版本
void QuickSortNonR(int* arr, int sz)
{
Stack st;
StackInti(&st);
StackPush(&st, sz - 1);//将右区间末端存入栈
StackPush(&st, 0);//将左区间末端存入栈
while (!StackEmpty(&st))
{
int left = StackTop(&st);
StackPop(&st);
int right = StackTop(&st);
StackPop(&st);
//int keyi = _QuickSortNonR1(arr, left, right);
int keyi = _QuickSortNonR2(arr, left, right);
if (keyi != -1)
{
StackPush(&st, right);
StackPush(&st, keyi + 1);
StackPush(&st, keyi - 1);
StackPush(&st, left);
}
}
StackDestroy(&st);
}
void MergeSortNonR(int* arr, int n)
{
//开临时空间
int* tmp = (int*)malloc(sizeof(int) * n);
if (tmp == NULL)
{
return;
}
int gap = 1;
while (gap < n)
{
int j = 0;//为了控制 tmp
for (int i = 0; i < n; i +=2*gap)
{
int begin1 = i, end1 = i + gap - 1;
int begin2 = i + gap, end2 = i + gap * 2 - 1;
//该部分如果满足就不会再向下运行代码 那还不如结束循环
if (end1 >= n || begin2 >= n)
{
break;
}
//if (end1 >= n)
//{
// end1 = n - 1;
// //[begin2,end2]修改成不存在的区间
// begin2 = n;
// end2 = n - 1;
//}
//else if (begin2 >= n)
//{
// //修改成不存在的区间
// begin2 = n;
// end2 = n - 1;
//}
if (end2 >= n)
{
end2 = n - 1;
}
while (begin1 <= end1 && begin2 <= end2)
{
if (arr[begin1] <= arr[begin2])
{
tmp[j++] = arr[begin1++];
}
else
{
tmp[j++] = arr[begin2++];
}
}
while (begin1 <= end1)
{
tmp[j++] = arr[begin1++];
}
while (begin2 <= end2)
{
tmp[j++] = arr[begin2++];
}
//将tmp中的数据拷贝到原数组中为下次排序做准备
//当然在上面那写超出范围后修正的区间 并没有移动
memcpy(arr + i, tmp + i, sizeof(int) * (end2 - i + 1));
}
gap *= 2;
}
free(tmp);
}
void BubbleSort(int* arr, int sz)
{
for (int i = 0; i < sz - 1; i++)
{
int falg = 0;
for (int j = 0; j < sz - i - 1; j++)
{
if (arr[j] > arr[j + 1])
{
falg = 1;
Swap(&arr[j], &arr[j + 1]);
}
}
if (falg == 0)
{
break;
}
}
}
void CountSort(int* arr, int sz)
{
int max = INT_MIN;
int min = INT_MAX;
for (int i = 0; i < sz; i++)//寻找该数据的区间端点
{
min = min > arr[i] ? arr[i] : min;
max = max < arr[i] ? arr[i] : max;
}
int* tmp = (int*)calloc((max - min + 1), sizeof(int));
int d = max - min;
for (int i = 0; i < sz; i++)
{
tmp[arr[i]-min]++;
}
int j = 0;//控制arr数组下标
for (int i = 0; i < sz; i++)
{
while(tmp[i]!=0)
{
arr[j++] = min + i;
tmp[i]--;
}
}
}
int main()
{
//int arr[] = { 3,2,1 };
int arr[] = { 9,8,7,6,5,4,3,2,1,10,12,0,11};
int sz = sizeof(arr) / sizeof(arr[0]);
//Print(arr, sz);
//非递归——快排
//QuickSortNonR(arr, sz);
//MergeSortNonR(arr, sz);
//Print(arr, sz);
Print(arr, sz);
/*printf("插入排序:");
InsertSort(arr, sz);*/
printf("希尔排序:");
CountSort(arr, sz);
//BubbleSort(arr, sz);
//ShellSort(arr, sz);
//SelectSort(arr, sz);
//HeapSort(arr, sz);
//QuickSort(arr,sz);
//MergeSort(arr, sz);
//快速排序非递归
//归并排序非递归
//三数取中
//
//小区间优化 —— 利用其他排序去优化归并排序 快速排序 降低归并排序和快速排序的递归深度
//快排优化三路
Print(arr, sz);
//Stack st;
//StackInti(&st);
//if (!StackEmpty(&st))
//{
// printf("栈为空\n");
//}
//StackPush(&st, 1);
//StackPush(&st, 2);
//StackPush(&st, 3);
//StackPush(&st, 4);
//StackPush(&st, 5);
//StackPush(&st, 6);
//StackPop(&st);
//StackPop(&st);
//StackPop(&st);
//printf("%d \n", StackTop(&st));
//if (StackEmpty(&st))
//{
// printf("栈为不为空\n");
//}
//StackDestroy(&st);
return 0;
}
栈的实现
stack.h
#define _CRT_SECURE_NO_WARNINGS 1
#include
#include
#include
typedef int StackData;
typedef struct Stack
{
StackData* arr;
int sz;
int capacity;
}Stack;
//栈的初始化
void StackInti(Stack* st);
//栈的插入
void StackPush(Stack* st,StackData x);
//出栈
StackData StackTop(Stack* st);
//栈的删除
void StackPop(Stack* st);
//栈的判空
bool StackEmpty(Stack* st);
//栈的销毁
void StackDestroy(Stack* st);
stack.c
#define _CRT_SECURE_NO_WARNINGS 1
#include"Stack_Queue.h"
void StackInti(Stack* st)
{
st->arr = NULL;
st->capacity = st->sz = 0;
}
void StackPush(Stack* st, StackData x)
{
if (st->capacity == st->sz)
{
int newcapacity = (st->capacity == 0) ? 4: st->capacity * 2;
StackData* tmp = (StackData*)realloc(st->arr, sizeof(StackData) * newcapacity);
if (tmp == NULL)
{
printf("failed to allocate memory.\n");
return;
}
st->arr = tmp;
st->capacity = newcapacity;
}
st->arr[st->sz++] = x;
}
void StackPop(Stack* st)
{
if(!StackEmpty(st))
st->sz--;
}
StackData StackTop(Stack* st)
{
if (!StackEmpty(st))
{
return st->arr[st->sz-1];
}
}
bool StackEmpty(Stack* st)
{
return st->sz == 0;
}
void StackDestroy(Stack* st)
{
st->arr = NULL;
st->capacity = st->sz = 0;
}
希望给位大佬指点一二 如有不对评论区指教或私信~ 代码有点小多 就不做文字讲解