小白学算法(16)希尔排序

142 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第20天,点击查看活动详情

希尔排序

1.介绍

希尔排序(Shell's Sort)是插入排序的一种又称“缩小增量排序”(Diminishing Increment Sort),是直接插入排序算法的一种更高效的改进版本。希尔排序是非稳定排序算法。该方法因 D.L.Shell 于 1959 年提出而得名。

希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至 1 时,整个文件恰被分成一组,算法便终止 --百度百科

图源 希尔排序 | 菜鸟教程 (runoob.com)

img

img

img

2.模板介绍

//传入两个参数,数组和长度
void exchangeShell(int arr[],int length) {
	//交换用的临时变量
    int temp;
    //记录希尔排序次数
	int count = 1;
    //外部进行增量的定义
	for (int i = length / 2; i > 0; i /= 2) {
		//内部 进行组内插入排序
        for(int j=i;j<length;j++){
            int k;
            int temp=arr[index];
            for(k=j-i;k>=&&temp<arr[k];k--){
                arr[k+i]=arr[k];
            }
            arr[k+i]=temp;
        }
		cout << "希尔排序第" << count++ << "次";
		Prinf(arr,length);
	}
}

正常插入排序

void InserSort(vector<int>&a,int length)
{
	for(int i=1;i<length;i++)
	{
		int temp=a[i];
		int j;
		//如果当前位数字小于前一位 那么就将前面的位置向后移一位 
		for(j=i-1;j>=0&&temp<a[j];j--)
		{
			a[j+1]=a[j];
		}
		//然后插入temp,因为j运行完for循环后是要向后移动的,所以最后j+1=temp 
		a[j+1]=temp;
		//1 3 2
		//1 3 3
	}
}

完整代码

#include<iostream>
using namespace std;
//交换排序的希尔排序
void Prinf(int arr[],int length) {
	for(int i=0; i<length; i++) {
		cout<<arr[i]<<" ";
	}
	cout<<endl;
}
void exchangeShell(int arr[],int length) {
}
int main() {
	int a[] = { 2,4,1,3 };
	int length=sizeof(a)/sizeof(int);
	exchangeShell(a,length);
	return 0;
}

问题:

为什么不在函数里面求数组长度,而是要传入一个length参数? c里面求数组长度是使用sizeof(arr)/sizeof(arr[0])

但函数接收数组参数后,sizeof(arr)/sizeof(arr[0]) 有问题

a[] 是长度计算的形式参数,在 main() 函数中调用时,a 是一个指向数组第一个元素的指针。在执行 main() 函数时,不知道 a 所表示的地址有多大的数据存储空间,只是告诉函数:一个数据存储空间首地址。

sizoef a 的结果是指针变量 a 占内存的大小,一般在 64 位机上是8个字节。a[0] 是 int 类型,sizeof a[0] 是4个字节

读者可以一试,得到的结果是2