我必须使用面向对象的方法实现三种不同的排序算法,我一直在考虑解决这个问题的最佳方法。
基本上,我认为它应该是这样的:
- >排序(类,接口,多态)
继承:
- >冒泡排序
- >插入排序
- > QuickSort
如果每种排序具有相同的接口,那么访问不同的排序方法会更容易,因此,当我来添加其他排序算法时,我可以轻松地将它们实现到当前的设计和类结构中
我的问题是:
这是一个很好的使用方法吗?
我可以使用模板吗?即如果我想使用Bubble,它会调用冒泡排序,如果我想使用Insertion它会调用Insertion吗?
答案 0 :(得分:5)
Sort
应该是一个接口或一个抽象类,而bubble / insertion / quick-sort应该是实现/具体类。
还值得了解以下内容:
策略模式:
http://en.wikipedia.org/wiki/Strategy_pattern
和
州模式:
http://en.wikipedia.org/wiki/State_pattern
至于模板,我不认为在你的情况下这是值得的。
答案 1 :(得分:3)
建议使用接口(纯虚拟类)
界面方法:
class sort_algorithm_interface {
public:
virtual void sort(std::vector<int>& input) const = 0;
};
class BubbleSort : public sort_algorithm_interface {
public:
virtual void sort(std::vector<int>& input) const {/* sort the input */}
};
class InsertionSort: public sort_algorithm_interface {
public:
virtual void sort(std::vector<int>& input) const {/* sort the input */}
};
class QuickSort: public sort_algorithm_interface {
public:
virtual void sort(std::vector<int>& input) const {/* sort the input */}
};
现在,当您想要对您进行排序时,请执行以下操作:
sort_algorithm_interface& s = QuickSort(input);
s.sort(input);
模板方法:
class BubbleSort {
public:
void sort(std::vector<int>& input) const {/* sort the input */}
};
class InsertionSort {
public:
void sort(std::vector<int>& input) const {/* sort the input */}
};
class QuickSort {
public:
void sort(std::vector<int>& input) const {/* sort the input */}
};
template<typename Sort>
class MySort {
void sort(std::vector<int>& input) {
Sort s;
s.sort(begin, end);
}
}
使用如下:
MySort<QuickSort> s;
s.sort(input);
答案 2 :(得分:2)
在C ++中执行此操作的正确方法是通过模板。
对事物进行排序是一种算法,它通常几乎没有持久状态。排序不是对象 - 它是数据的函数(可以是对象)。
std
库已有一个排序,带有此签名:
template<typename I, typename C = std::less<typename std::iterator_traits<I>::value_type> >
void sort(I begin, I end, C comp = C());
迭代器begin
和end
表示要排序的值范围,而comp是一个仿函数(或函数),当传递值范围的两个元素时,会告诉您是否第一个小于第二个。
要在std::vector
上使用此功能,您可以执行以下操作:
std::vector<int> myVector; // assume it has some data in it
sort( myVector.begin(), myVector.end() );
std :: sort是(通常是?)快速排序。但该界面适用于快速,冒泡和插入排序。
这种方法的一大优点是一种可以使用另一种方法。例如,虽然快速排序在大型数据集上更快,但通常在小型数据集上,插入排序的简单性获胜(较低的常数因子,即使有n ^ 2开销)。因此,通过编写这样的类型,当元素数量很少时,quicksort的递归调用可以成为插入排序。
现在,如果你需要运行时替换你正在使用的算法,你需要确定你正在使用的迭代器,甚至可能是比较器。这可以通过常见的函数签名(我要做的)或带有纯虚拟接口的基类(我建议反对)来完成。请注意,运行时选择的比较器的开销是非常重要的。固定迭代器选择,或指向函数或虚拟方法调用的开销,只要不在算法的递归调用中完成,对任何合理大小的容器来说都是相当便宜的。