模板——快速排序(2种写法)

法一:只用一个模板参数 

当比较自定义类型时,再重载自定义类型的<运算符

#include <iostream>
#include <vector>
#include <math.h>

using std::cout;
using std::endl;
using std::vector;

template<typename T>
class MyQsort
{
public:
    MyQsort(T *arr, size_t size)//, Compare com
    :_vec(arr,arr+size)
    {
    }
    void quick(int left, int right);//, Compare &com
    int partition(int left, int right);//, Compare &com
    void print();
private:
    vector<T> _vec;
};

template<typename T>
void MyQsort<T>::quick(int left, int right)
{
    if(left<right)
    {
        //split左边的元素<_vec[split],右边的元素>_vec[split]
        int split=partition(left,right);
        quick(left,split-1);//对split左边的元素进行排序
        quick(split+1,right);//对split右边的元素进行排序
    }
}

template<typename T>
int MyQsort<T>::partition(int left, int right)
{
    T tem=_vec[left];
    int i=left;
    int j=right;
    while(i<j)
    {
        while(tem<_vec[j]&&i<j)
        {
            j--;
        }
        if(i<j)
        {
            _vec[i]=_vec[j];
            i++;
        }
        while(_vec[i]<tem&&i<j)
        {
            i++;
        }
        if(i<j)
        {
            _vec[j]=_vec[i];
            j--;
        }
    }
    _vec[i]=tem;
    return i;
}

template<typename T>
void MyQsort<T>::print()
{
    for(auto &elem:_vec)
    {
        cout<<elem<<" ";
    }
    cout<<endl;
}

class Point
{
public:
    Point()
    :_x(0)
    ,_y(0)
    {
    }
    Point(int x,int y)
    :_x(x)
    ,_y(y)
    {
    }
    float getDistance() const
    {
        return hypot(_x, _y);
    }
private:
    int _x;
    int _y;
    friend bool operator<(const Point &lhs,const Point &rhs);
    friend std::ostream &operator<<(std::ostream &os,const Point &rhs);
};

bool operator<(const Point &lhs,const Point &rhs)
{
    if(lhs.getDistance() < rhs.getDistance())
    {
        return true;
    }
    else if(lhs.getDistance() == rhs.getDistance())
    {
        if(lhs._x < rhs._x)
        {
            return true;
        }
        else if(lhs._x == rhs._x)
        {
            if(lhs._y < rhs._y)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        else
        {
            return false;
        }
    }
    else
    {
        return false;
    }
}

std::ostream &operator<<(std::ostream &os,const Point &rhs)
{
    os<<"("<<rhs._x<<","<<rhs._y<<")";
    return os;
}

void test()
{
    int a[5]={4,1,1,65,3};
    MyQsort<int>mq(a,5);
    mq.quick(0,4);
    mq.print();
    Point pt[5]={Point(2,1),Point(1,1),Point(4,1),Point(3,1),Point(5,5)};
    MyQsort<Point>mp(pt,5);
    mp.quick(0,4);
    mp.print();
}
int main()
{
    test();
    return 0;
}

 

 

法二:用到两个模板参数(第一个模板参数是类型,第二个模板参数制定了使用此参数时会进行什么操作)

#include <iostream>
#include <vector>
#include <math.h>

using std::cout;
using std::endl;
using std::vector;



template<typename T , typename Compare = std::less<T>>//Compare默认参数是std::less,std::less是std库里的类,此类默认实现的是内置类型的<比较
class MyQsort
{
public:
	MyQsort(T *arr , size_t size)//, Compare com
		:_vec(arr , arr + size)
	{
	}
	void quick(int left , int right);//, Compare &com
	int partition(int left , int right);//, Compare &com
	void print();
private:
	vector<T> _vec;
};

template<typename T , typename Compare>
void MyQsort<T , Compare>::quick(int left , int right)
{
	if (left < right)
	{
		//split左边的元素<_vec[split],右边的元素>_vec[split]
		int split = partition(left , right);
		quick(left , split - 1);//对split左边的元素进行排序
		quick(split + 1 , right);//对split右边的元素进行排序
	}
}

template<typename T , typename Compare>
int MyQsort<T , Compare>::partition(int left , int right)
{
	T tem = _vec[left];
	int i = left;
	int j = right;
	Compare com;
	while (i < j)
	{
		while (com(tem , _vec[j]) && i < j) //等价于:com.operator()(tem , _vec[j])
		{
			j--;
		}
		if (i < j)
		{
			_vec[i] = _vec[j];
			i++;
		}
		while (com(_vec[i] , tem) && i < j)
		{
			i++;
		}
		if (i < j)
		{
			_vec[j] = _vec[i];
			j--;
		}
	}
	_vec[i] = tem;
	return i;
}

template<typename T , typename Compare>
void MyQsort<T , Compare>::print()
{
	for (auto &elem : _vec)
	{
		cout << elem << " ";
	}
	cout << endl;
}

struct MyCompare;//类的前向声明

class Point
{
public:
	Point()
		:_x(0)
		, _y(0)
	{
	}
	Point(int x , int y)
		:_x(x)
		, _y(y)
	{
	}
	float getDistance() const
	{
		return hypot(_x , _y);
	}
private:
	int _x;
	int _y;
	friend std::ostream &operator<<(std::ostream &os , const Point &rhs);
	friend struct MyCompare;
};

struct MyCompare	//模板的第二个参数:自定义函数对象
{
	//自己实现std::less<Point>的功能
	bool operator()(const Point &lhs , const Point &rhs)
	{
		if (lhs.getDistance() < rhs.getDistance())
		{
			return true;
		}
		else if (lhs.getDistance() == rhs.getDistance())
		{
			if (lhs._x < rhs._x)
			{
				return true;
			}
			else if (lhs._x == rhs._x)
			{
				if (lhs._y < rhs._y)
				{
					return true;
				}
				else
				{
					return false;
				}
			}
			else
			{
				return false;
			}
		}
		else
		{
			return false;
		}
	}
};

std::ostream &operator<<(std::ostream &os , const Point &rhs)
{
	os << "(" << rhs._x << "," << rhs._y << ")";
	return os;
}

namespace  std	//std库
{
	template <>
	//模板第二个参数默认是std::less
	//未做特化前,std::less只能用于内置类型
	//在std空间里做了针对Point的特化,使std::less也可用于自定义类型Point
	struct less<Point>	
	{
		bool operator()(const Point &lhs , const Point &rhs)
		{
			if (lhs.getDistance() < rhs.getDistance())
			{
				return true;
			}
			else	//这里偷懒少写了一些比较情况
			{
				return false;
			}
		}
	};
};

void test()
{
	int a[5] = { 4,1,1,65,3 };
	MyQsort<int>mq(a , 5);
	mq.quick(0 , 4);
	mq.print();
	Point pt[5] = { Point(2,1),Point(1,1),Point(4,1),Point(3,1),Point(5,5) };
	MyQsort<Point , MyCompare> mp(pt , 5);//用自定义的MyCompare实现Point的<比较
	mp.print();
	mp.quick(0 , 4);
	mp.print();
	MyQsort<Point> mp2(pt , 5);	//用特化的std::less<Point>实现Point的<比较
	//std::less<Point>是默认参数
	//等价于MyQsort<Point,std::less<Point>> mp2(pt , 5);
	mp2.quick(0 , 4);
	mp2.print();
}
int main()
{
	test();
	return 0;
}

 

 

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值