我们在之前学习了各种排序的算法,那么我们的排序类(Sort)和数组类(Array)之间的关系如下。
那么我们需要将排序类和数组类之间关联起来,怎么进行关联呢?我们需要在排序类中新增几个成员函数,具体函数原型如下
具体代码如下,我们在 Array.h 中添加如下代码
T* array() const
{
return m_array;
}
上面函数用来获取 array 的头地址。Sort.h 代码如下
template <typename T>
static void Select(Array<T>& array, bool min2max = true)
{
Select(array.array(), array.length(), min2max);
}
template <typename T>
static void Insert(Array<T>& array, bool min2max = true)
{
Insert(array.array(), array.length(), min2max);
}
template <typename T>
static void Bubble(Array<T>& array, bool min2max = true)
{
Bubble(array.array(), array.length(), min2max);
}
template <typename T>
static void Shell(Array<T>& array, bool min2max = true)
{
Shell(array.array(), array.length(), min2max);
}
template <typename T>
static void Merge(Array<T>& array, bool min2max = true)
{
Merge(array.array(), array.length(), min2max);
}
template <typename T>
static void Quick(Array<T>& array, bool min2max = true)
{
Quick(array.array(), array.length(), min2max);
}
我们在 main.cpp 中添加如下测试代码
#include <iostream>
#include "Sort.h"
#include "StaticArray.h"
using namespace std;
using namespace DTLib;
int main()
{
StaticArray<int, 5> sa;
for(int i=0; i<5; i++)
{
sa[i] = i;
}
Sort::Bubble(sa, false);
for(int i=0; i<5; i++)
{
cout << sa[i] << endl;
}
return 0;
}
排序结果如下
我们看到已经正确进行排序。那么在排序的工程应用中,有个经典的问题:那就是当待排数据元素为体积庞大的对象时,我们应如何提高排序的效率呢?我们以下来的示例代码作为分析
#include <iostream>
#include <ctime>
#include "Sort.h"
using namespace std;
using namespace DTLib;
struct Test : public Object
{
int id;
int data1[1000];
double data2[500];
bool operator < (const Test& obj)
{
return id < obj.id;
}
bool operator >= (const Test& obj)
{
return id >= obj.id;
}
bool operator > (const Test& obj)
{
return id > obj.id;
}
bool operator <= (const Test& obj)
{
return id <= obj.id;
}
};
Test t[1000];
int main()
{
clock_t begin = 0;
clock_t end = 0;
for(int i=0; i<1000; i++)
{
t[i].id = i;
}
begin = clock();
Sort::Bubble(t, 1000, false);
end = clock();
cout << "Time : " << (end - begin) << endl;
return 0;
}
我们来看看花费的时间,结果如下
我们看到花费时间很长。那么我们来分析下。在排序过程中,要不可避免的进行交换操作;然而交换操作的本质是数据元素间的相互复制,如当数据元素体积较大时,交换操作耗时巨大。我们来看看经典的做法:代理模式。
1、为待排数据元素设置代理对象;
2、对代理对象所组成的序列进行排序;
3、需要访问有序数据元素时,通过访问代理序列完成。
也就是说,我们通过操作代理对象进而来操作原来的数据对象。如下:
代理效果如下图所示
我们看到用小对象数据来代替大对象数据,具体代码如下
#include <iostream>
#include <ctime>
#include "Sort.h"
using namespace std;
using namespace DTLib;
struct Test : public Object
{
int id;
int data1[1000];
double data2[500];
bool operator < (const Test& obj)
{
return id < obj.id;
}
bool operator >= (const Test& obj)
{
return id >= obj.id;
}
bool operator > (const Test& obj)
{
return id > obj.id;
}
bool operator <= (const Test& obj)
{
return id <= obj.id;
}
};
class TestProxy : public Object
{
protected:
Test* m_pTest;
public:
int id()
{
return m_pTest->id;
}
int* data1()
{
return m_pTest->data1;
}
double* data2()
{
return m_pTest->data2;
}
Test& test() const
{
return *m_pTest;
}
bool operator < (const TestProxy& obj)
{
return test() < obj.test();
}
bool operator >= (const TestProxy& obj)
{
return test() >= obj.test();
}
bool operator > (const TestProxy& obj)
{
return test() > obj.test();
}
bool operator <= (const TestProxy& obj)
{
return test() <= obj.test();
}
Test& operator = (Test& test)
{
m_pTest = &test;
return test;
}
};
Test t[1000];
TestProxy pt[1000];
int main()
{
clock_t begin = 0;
clock_t end = 0;
for(int i=0; i<1000; i++)
{
t[i].id = i;
pt[i] = t[i];
}
begin = clock();
Sort::Bubble(pt, 1000, false);
end = clock();
cout << "Time : " << (end - begin) << endl;
return 0;
}
结果如下
我们看到效率提高了50倍左右,这就是经典的代理类模式。我们通过对代理类的学习,总结如下:1、当排序体积是很庞大的对象时,使用代理模式间接完成;2、代理模式的使用有效避开大对象交换时的耗时操作;3、代理模式解决方案是空间换时间思想的体现。
转载于:https://blog.51cto.com/12810168/2409426