数据结构与算法分析-C++描述 第7章 谢尔排序(shellSort)

本文深入解析谢尔排序算法,一种通过比较一定间隔的元素进行排序的方法。文章详细介绍了谢尔排序的行为描述、算法流程及其实现,同时探讨了不同增量序列(如谢尔增量、Hibbard增量和sedgewick增量)对排序效率的影响。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

谢尔排序(shellSort):

        通过比较一定间隔的元素进行工作,各趟比较随着算法的进行而减小,直到只比较相邻元素的最后一趟元素排序结束,因此谢尔排序有时也称缩减增量排序(diminishing increment sort).

行为描述:

算法描述:

        谢尔排序使用一个序列h_1, h_2, \ ... \ h_k,叫做增量序列(increment sequence)。 只要h_1=1,任何增量序列都是可行,不过有些增量序列比另一些增量序列好(如shell增量,Hibbard增量,sedgewick增量)。在使用增量h_k的一趟排序之后,对于每一个i有:a[i] \leq a[i+h_k],此时称文件为h_k的排序。

谢尔排序的性质:

        一个h_k排序的文件保持它的h_k排序性;

        定理:使用谢尔增量排序的最坏情形运行时间为O(N^2)。【当N = 2^k时,将第i个元素恢复到正确位置需要移动i-1次 \sum _{i = 1}^{N/2}(i-1) = O(N^2)

        定理:使用Hibbard增量排序的最坏情形运行时间为O(N^{3/2})。【增量序列:1 , 3, 5, 7, ... , 2^k -1。当对h_k排序时,h_{k+1},h_{k+2}已经为有序序列,而且h_{k+2} = \alpha h_{k+1} + \beta h_k \ \ \ \alpha , \beta \in N^*

总的运行时间:O(\sum_{i = 1}^{i = N/2} Nh_k + \sum_{i = N/2}^N N^2/h_k) = O(Nh_{N/2})+O(N^2/h_{N/2}) = O(N^{3/2})

        定理:使用sedgewick增量排序的最坏情形运行时间为O(N^{4/3})【增量序列:1, 5,19,41, ...,9 \times 4^i - 9 \times 2^i +1 或4^i - 3\times 2^i +1】。

谢尔增量排序实例:

//shellSort.cpp
#include<iostream>
#include<vector>

using namespace std;

template<class Compareable>
void shellSort(vector<Compareable> &v){
	//update gap
	for(int gap = v.size() / 2; gap > 0; gap /= 2){
		//traverse vector
		for(int i = gap; i < v.size(); i++){
			Compareable temp = v[i];
			int j = i;
			//find the proper location
			for(; j >= gap && temp < v[j - gap]; j -= gap){
				v[j] = v[j - gap];
			}
			//insert into the proper location;
			v[j] = temp;
		}
	}
}

int main(){
	int arr[] = {81, 94, 11, 96, 12, 35, 17, 95, 28, 58, 41, 75, 15};
	int len = sizeof(arr) / sizeof(arr[0]);
	vector<int> v;
	for(int i = 0 ; i < len; i++){
		v.push_back(arr[i]);
	}
	
	cout << "******* the original data ***********" << endl;
	for(typename vector<int>::iterator itr = v.begin(); itr != v.end(); ++itr){
		cout << *itr << " ";
	}
	cout << endl;
	
	cout << "******* the sorted data ***********" << endl;
	shellSort(v);
	for(typename vector<int>::iterator itr = v.begin(); itr != v.end(); ++itr){
		cout << *itr << " ";
	}
	cout << endl;
	
	cout << " done ." << endl;
	return 0;
}

practice makes perfect !

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值