策略模式(Strategy):它定义了算法家族,分别封装起来,让它们之间可以相互替换,此模式让算法的变化,不会影响到使用算法的客户。
排序接口:
isort.h
#pragma once
class ISort
{
public:
virtual ~ISort() {}
virtual void doSort(int a[], int len) = 0;
};
冒泡排序算法类bobbleSort.h
#pragma once
#include "isort.h"
class BobbleSort : public ISort
{
public:
void doSort(int arr[], int len) override
{
if (len <= 1)
return;
int temp; //此算法有改进方式,这里主要为了演示设计模式
for (int i = 0; i < len - 1; i++)
{
for (int j = 1; j < len - i; j++)
{
if (arr[j] < arr[j - 1])
{
temp = arr[j];
arr[j] = arr[j - 1];
arr[j - 1] = temp;
}
}
}
}
};
插入排序算法类insertSort.h:
#pragma once
#include "isort.h"
class InsertSort : public ISort
{
public:
void doSort(int arr[], int len) override
{
if (len <= 1)
return;
int temp;
for (int i = 1; i < len; i++)
{
for (int j = i - 1; j >= 0; j--)
{
if (arr[j] > arr[j + 1])
{
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
else
{
break;
}
}
}
}
};
选择排序算法类selectSort:
#pragma once
#include "isort.h"
class SelectSort : public ISort
{
public:
void doSort(int arr[], int len) override
{
if (len <= 1)
return;
int temp;
for (int i = 0; i < len - 1; i++)
{
int minIndex = i;
for (int j = i + 1; j < len; j++)
{
if (arr[j] < arr[minIndex])
minIndex = j;
}
temp = arr[i];
arr[i] = arr[minIndex];
arr[minIndex] = temp;
}
}
};
快速排序算法类quickSort.h
#pragma once
#include "isort.h"
class QuickSort : public ISort
{
public:
void doSort(int arr[], int len) override
{
if (len <= 1)
return;
quickSort(arr, 0, len-1);//注意最后一个参数是len-1
}
private:
int quickSortPartition(int s[], int l, int r) {
//Swap(s[l], s[(l + r) / 2]); //若以中间数为基准,则先将中间的这个数和第一个数交换即可
int i = l, j = r, x = s[l]; //将最左元素记录到x中
while (i < j)
{
// 从右向左找第一个<x的数
// 无需考虑下标越界
while (i < j && s[j] >= x)
j--;
if (i < j)
s[i++] = s[j]; //直接替换掉最左元素(已在x中存有备份)
// 从左向右找第一个>x的数
while (i < j && s[i] <= x)
i++;
if (i < j)
//替换掉最右元素(已在最左元素中有备份)
//最左元素一定被覆盖过,若没有,则表明右侧所有元素都>x,那么算法将终止
s[j--] = s[i];
}
s[i] = x; //i的位置放了x,所以其左侧都小于x,右侧y都大于x
return i;
}
void quickSort(int s[], int l, int r)
{
//数组左界<右界才有意义,否则说明都已排好,直接返回即可
if (l >= r) {
return;
}
// 划分,返回基准点位置
int i = quickSortPartition(s, l, r);
// 递归处理左右两部分,i处为分界点,不用管i了
quickSort(s, l, i - 1);
quickSort(s, i + 1, r);
}
};
context.h
#pragma once
#include "isort.h"
class Context
{
public:
Context(ISort *sortBase)
{
m_sortBase = sortBase;
}
void startSort(int arr[], int len)
{
if (m_sortBase != nullptr)
{
m_sortBase->doSort(arr, len);
}
}
private:
ISort *m_sortBase;
};
客户端程序:
#include "context.h"
#include <iostream>
#include "bobbleSort.h"
#include "quickSort.h"
#include "insertSort.h"
#include "selectSort.h"
//数组打印
void printArray(int a[], int len)
{
for (int i = 0; i < len; ++i)
std::cout << a[i] << " ";
std::cout << std::endl;
}
int main()
{
const int len = 5;
int arr[len] = { 3, -5, -6, 5, 6 };
printArray(arr, len);
std::cout << "排序后:" << std::endl;
ISort* sortAlgorithm = new QuickSort(); //或者ISort* sortAlgorithm = new QuickSort();根据需要选择算法类
Context* context = new Context(sortAlgorithm);
context->startSort(arr, len);
printArray(arr, len);
delete sortAlgorithm;
delete context;
getchar();
return 0;
}
运行结果:
3 -5 -6 5 6
排序后:
-6 -5 3 5 6
参考:
策略模式-排序算法