#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <memory.h>
/*
八大排序
难易程度:
4个简单:直接插入排序
4个难:希尔排序
(代码实现话,如果是简单排序,则代码就是双重for循环,里面套一个if)(除了基数)
稳定性:
4个稳定:直接插入排序
4个不稳定:希尔排序
*/
//时间复杂度O(n^2) 空间复杂度O(1) 稳定性:稳定
void Insert_Sort(int arr[], int len)
{
for (int i = 1; i < len; i++)//控制的是趟数
{
int tmp = arr[i];
int j = i - 1;
for (; j >= 0; j--)//控制的是对已排序好的序列的从右至左的访问
{
if (arr[j] > tmp)//如果比我取出来的值tmp,向后挪动
{
arr[j+1] = arr[j];
}
else
{
break;//情况1:遇到了不大于我的值,停下来,把值放回去
}
}
//情况2:越界了,停下来,把值放回去
arr[j+1] = tmp;
}
}
void Show(int arr[], int len)
{
for (int i = 0; i < len; i++)
printf("%d ", arr[i]);
printf("\n");
}
//这个函数代表希尔排序中的单趟处理
void Shell(int arr[], int len, int gap_val)
{
//此时增量为5
//需要此时将每一个组执行直接插入排序
for (int i = gap_val; i < len; i++)//此时i控制的需要往前插入的待排序值
{
int tmp = arr[i];
int j = i - gap_val;
for (; j >= 0; j-=gap_val)//控制的是对已排序好的序列的从右至左的访问
{
if (arr[j] > tmp)//如果比我取出来的值tmp,向后挪动
{
arr[j + gap_val] = arr[j];
}
else
{
break;//情况1:遇到了不大于我的值,停下来,把值放回去
}
}
//情况2:越界了,停下来,把值放回去
arr[j + gap_val] = tmp;
}
}
//希尔排序时间复杂度取决于缩小增量的赋值 O(n^1.3 ~ n^1.7) 或者O(n^1.5) 空间复杂度O(1) 稳定性:不稳定
void Shell_Sort(int arr[], int len)
{
int Gap[] = { 5,3,1 };
int len_Gap = sizeof(Gap) / sizeof(Gap[0]);
for (int i = 0; i < len_Gap; i++)//趟数
{
Shell(arr, len, Gap[i]);
}
}
int main()
{
int arr[] = { 109,75,20,91,4,75,90,170,15,92,7,5,40,91,7906,15,7,209,56,71,90,54 };
int len = sizeof(arr) / sizeof(arr[0]);
printf("排序之前:\n");
Show(arr, len);
//Insert_Sort(arr, len);
Shell_Sort(arr, len);
printf("排序之后:\n");
Show(arr, len);
return 0;
}