数据结构与算法分析-C++描述 第7章 间接排序(indirectionSort)

间接排序(indirectionSort):

        直接应用基于谢尔排序快速排序等这些算法的函数模板时,如果要排序的Comparable对象很大时,有时效率是很低的,问题在于,重新排列的Comparable对象时,进行了太多的复制工作,如果Comparable对象很大且难以复制,则代价将是很大的。解决的办法是:生成一个指向Comparable对象的指针数组,然后重新排列这些指针。一旦确定了元素应该在的位置,就可以直接将该元素放在相应的位置上,而不必过多的中间复制操作。这需要使用称为中间置换(in-situ permutation)的算法。【用C++实现的时候需要一些新的语法】

行为描述:

算法描述:

        第一步:生成指针数组。令a为要排序的数组,p为指针数组。初始化后p[i]指向a[i];

        第二步:使用p[i]所指的对象的值来确定p[i]的顺序并对p[i]排序[快速排序]。在数组a的对象完全不动,而数组p的指针重新排序。

        第三步:移位实现p[i]回填到a[i]中;

C++特性:

        1)vector<Comparable*>不运行

        quickSort(p)重新排列指针时,quickSort模板算法为Comparable*,因此需要能够比较两个Comparable* 类型的“<”操作符。这种操作符对于指针变量是存在的,但对指针所指向的Comparable值却什么都不做。

        2)智能指针类

        包含指针动作的类有时候也称智能指针类(smart pointer classes)。这个类比普通指针高级一些,因为如果没有赋初始值时,将自动赋值为NULL。

        3)重载operator<

        将<用于所指的Comparable对象。

        4)重载类型转换操作符

        operator Comparable *()const将从一个Pointer<Comparable>转换为Comparable*类型,因此,p[i] = &a[i]隐式转换成立;

        5)指针减法运算

        nextj = p[j] - &a[0] 表示p[j]与起始地址的偏移距离;

间接排序的性质:

        间接排序是由快速排序为解决内存不足而采取的改进算法,拥有快速排序的一般特性,其另一显著优势在于提高时间和空间利用率(减少复制操作次数)

间接排序实例:

//indirectionSort.cpp
#include<iostream>
#include<vector>
#include<algorithm>

using namespace std;

template<class Comparable>
class Pointer{
public:
	//Pointer constructor
	Pointer(Comparable *p = NULL):pointee(p){
	
	};
	
	//operator< overwrite
	bool operator<(const Pointer &p) const{
		return (*pointee < *p.pointee);
	};
	//access the pointer value
	operator Comparable * ( ) const{
		return pointee;
	};
	
private:
	Comparable *pointee;
};

template<class Comparable>
void indirectionSort(vector<Comparable> &v);

//quickSort vector v
template<class Comparable>
void quickSort(vector<Comparable> &v);

//find median in vector v from index left, center, right
template<class Comparable>
const Comparable & median3(vector<Comparable> &v, int left, int right);

//quickSort the inner part
template<class Comparable>
void quickSort(vector<Comparable> &v, int left, int right);

//backup sort when vector size is smaller than 10
template<class Compareable>
void inserationSort(vector<Compareable> &v, int left, int right);

//main function
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;
	indirectionSort(v);
	for(typename vector<int>::iterator itr = v.begin(); itr != v.end(); ++itr){
		cout << *itr << " ";
	}
	cout << endl;
	
	cout << " done ." << endl;
	return 0;
}

template<class Comparable>
void indirectionSort(vector<Comparable> &v){
	vector<Pointer<Comparable> > p(v.size());
	int i, j, nextj;
	//copy vector v into p
	for(i = 0; i < v.size(); i++){
		p[i] = &v[i];			//background construt temp variable
	}
	cout << endl;
	//sort p
	quickSort(p);
	cout << " the sorted p is : ";
	for(i = 0; i < v.size(); i++){
		cout << *p[i] << " ";
	}
	cout << endl;
	//restore p into v
	for(i = 0; i < v.size(); i++){
		if(p[i] != &v[i]){		//implicit convert Pointer<Comparable> p to Comparable* p
			Comparable temp = v[i];
			//find the proper index of v[i]
			for(j = i; p[j] != &v[i]; j = nextj){
				nextj = p[j] - &v[0];	//the distance betweent v[i] and v[0]
				v[j] = *p[j];
				p[j] = &v[j];
			}
			//insert v[i]
			v[j] = temp;
			//update p[j]/p[i]
			p[j] = &v[j];
		}
	}	
}

template<class Comparable>
void quickSort(vector<Comparable> &v){
	quickSort(v, 0, v.size() - 1);
}

template<class Comparable>
const Comparable & median3(vector<Comparable> &v, int left, int right){
	int center = (left + right) / 2;
	//cout << v[left] << " , " << v[center] << " , " << v[right];
	//sort the left, center and right in order
	if(v[center] < v[left]){
		swap(v[left], v[center]);
	}
	if(v[right] < v[left]){
		swap(v[left], v[right]);
	}
	if(v[right] < v[center]){
		swap(v[center], v[right]);
	}
	//cout << " : median is " << v[center] << endl;
	swap(v[center], v[right -1]);		//place the median to the last index
	return v[right - 1];
}

template<class Comparable>
void quickSort(vector<Comparable> &v, int left, int right){
	if(left + 10 <= right){ 	// using the quickSort when vector size is larger than 10
		Comparable pivot = median3(v, left, right);
		int i = left, j = right - 1;
		for(;;){
			while(v[++i] < pivot){};	//find the j's warning mark
			while(pivot < v[--j]){};	//find the i's warning mark
			if(i < j){
				swap(v[i], v[j]);		//swap the warning mark
			}else{
				break;
			}
		}
		swap(v[i], v[right - 1]);		//restore the pivot
		quickSort(v, left, i - 1);		//iterative quickSort the left part
		quickSort(v, i + 1, right);		//iterative quickSort the right part
	}else{								//using the inserationSort when vector size is smaller than 10
		inserationSort(v, left, right + 1);
	}
}

template<class Compareable>
void inserationSort(vector<Compareable> &v, int left, int right){
	if(left < right){
		int j;
		//traverse the vector form left to right
		for(int p  = left; p < right; p++){
			Compareable temp = v[p];
			//find the proper location
			for(j = p; j > 0 && temp < v[j - 1]; j--){
				v[j] = v[j - 1];
			}
			//insert into proper location
			v[j] = temp;
		}
	}
}

practice makes perfect !

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值