插入排序优化之希尔排序详解


一、概念及说明

希尔排序-----插入排序的一种,属于优化后的插入排序

原理:把数组中的数据进行分组,在组内进行排序,没有排列好继续分组(注意改分组需要调整每个组元素的个数),每次排序都是在组内进行排序

例如数组中有15个元素为例,第一次分组为 15/2 =7-1=6 第二次分组为7/2=3-1=2 算出来的数为元素间隔数。

相比于插入排序的优点是:1.减少查找次数 2.减少元素移动的次数

二、使用说明

1.时间复杂度

当增量大于1的时候,关键字较小的记录就不是一步步地挪动,而是跳跃式地移动,从而使得在进行最后一趟增量为1的的插入排序中,序列已经基本有序,只要做少量的比较和移动即可完成排序,因此希尔排序的排序的时间复杂度比直接插入排序的低。希尔排序的时间复杂度取决于增量的选取。当n在某个特定的范围内,希尔排序所需的比较和移动次数大概为n^1.3。

2.空间复杂度

只需要一个记录的辅助空间r[0],所以空间复杂度为O(1)。

3.算法特点

  1. 记录跳跃式地移动导致排序方法是不稳定的。
  2. 只能用于顺序结构,不能用于链式结构。
  3. 增量序列可以有各种取法,但应该使增量序列中的值没有除1之外的公因子,并且最后一个增量值必须等于1。
  4. 记录总的比较次数和移动次数比直接插入排序要少,n越大时,效果越明显。所以适合初始记录无序、n较大时的情况。

4.动画演示

在这里插入图片描述

三、代码演示

#include <stdio.h>
#include <stdlib.h>

void GroupSort(int* arr, int len, int iStep, int i)
{
    
    
	int ii = 0, jj = 0;
	int temp = 0;
	//这里面相当于插入排序
	for (ii = i + iStep; ii < len; ii += iStep)
	{
    
    
		temp = arr[ii];
		for (jj = ii - iStep; jj >= 0; jj -= iStep)
		{
    
    
			if (arr[jj] <= temp)
				break;
			arr[jj + iStep] = arr[jj];
		}
		arr[jj + iStep] = temp;
	}
}
/* 
 * ShellSort()和GroupSort()是将希尔排序分步来做
 * 先分组,再将组内的元素进行插入排序,增量从大到小,就完成了排序
 */
void ShellSort(int *arr,int len)
{
    
    
	int iStep;
	int i;
	//这里面进行的是分组任务
	for (iStep = len / 2; iStep > 0; iStep = iStep / 2)
	{
    
    
		for ( i = 0; i < len; ++i)
		{
    
    
			GroupSort(arr,len,iStep,i);
		}
	}
}


/*
 * 整个希尔排序的过程如下 
 */
void shellSort(int *array, int len)
{
    
    
	int i, j, k, temp, gap;

	for (gap = len / 2; gap >= 1; gap /= 2)
	{
    
    
		for (k = 0; k < len; ++k){
    
    

			for (i = k + gap; i < len; i += gap)
			{
    
    
				temp = array[i];
				for (j = i - gap; j >= 0 && temp < array[j]; j -= gap)
					array[j + gap] = array[j];
				array[j + gap] = temp;
			}
		}
	}
}

void printArray(int *array,int len)
{
    
    
	for (int i = 0; i < len; ++i)
	{
    
    
		printf("%4d", array[i]);
	}
}

int main(void)
{
    
    
	int array[10] = {
    
     78,15,99,53,84,27,39,1,41,67 };
	int len = sizeof(array) / sizeof(int);

	//输出排序前的数组
	printf("排序前的数组\n");
	printArray(array, len);
	putchar('\n');

	//调用希尔排序函数排序
	//shellSort(array, len);
	ShellSort(array, len);

	//输出排序后的数组
	printf("排序后的数组\n");
	printArray(array, len);
	putchar('\n');

	system("pause > 0");
	return 0;
}

代码运行结果如下:
在这里插入图片描述
在这里插入图片描述

Guess you like

Origin blog.csdn.net/weixin_51363326/article/details/121375684