本文存储的是自己实现的一个模板数组类(为了练习排序)
模板
//排序数组 存在MySort_vector.hpp
template<typename Elemtype>
class MyArray {
private:
Elemtype* arr;
int size;
public:
MyArray(int getSize = 0) :size(getSize) {}
void Swap(Elemtype* a, Elemtype* b);
void Array_init();
void show();
void Bubble_sort();
void Select_sort();
void Insert_sort();
void Shell_sort();
void Quick_sort(int begin, int end);
void Radix_sort();
void Merge_sort(int left, int right);//核心递归函数
void Merge_in_arr(int left, int mid, int right);//合并函数
Elemtype Binary_search(Elemtype data);
};
template<typename Elemtype>
void MyArray<Elemtype>::Swap(Elemtype* a, Elemtype* b)
{
Elemtype temp = *a;
*a = *b;
*b = temp;
}
template<typename Elemtype>
void MyArray<Elemtype>::Array_init()
{
arr = new Elemtype[size]();
for (int i = 0; i < size; ++i)
{
std::cin >> arr[i];
}
}
template<typename Elemtype>
void MyArray<Elemtype>::show()
{
for (int i = 0; i < size; ++i)
{
std::cout << arr[i] << " ";
}
std::cout << std::endl;
}
//冒泡排序
template<typename Elemtype>
void MyArray<Elemtype>::Bubble_sort()
{
if (size <= 0)
{
return;
}
int length = size;
int flag = 0; //作为是否交换的标记
while (length--)
{
for (int i = 0; i < length; i++)
{
if (arr[i] > arr[i + 1])
{
Swap(arr + i, arr + i + 1);
flag = 1;
}
}
if (0 == flag) // //提高效率,如果中途就排好了,就提前退出
return;
}
}
//选择排序
template<typename Elemtype>
void MyArray<Elemtype>::Select_sort()
{
if (size <= 0)
return;
int begin = 0, end = size - 1;
while (begin < end)
{
int max = begin, min = end;
for (int i = begin; i <= end; ++i)
{
if (arr[i] > arr[max]) max = i;
if (arr[i] < arr[min]) min = i;
}
++begin;
--end;
}
}
template<typename Elemtype>
void MyArray<Elemtype>::Insert_sort()
{
if (size <= 0)
return;
for (int i = 0; i < size - 1; ++i)
{
int end = i;
Elemtype temp = arr[end + 1];
while (end >= 0)
{
if (arr[end] > temp)
{
arr[end + 1] = arr[end];
--end;
}
else
{
break;
}
}
arr[end + 1] = temp; //有两种可能
//1.待插入元素找到应插入位置(break跳出循环到此)
//2.待插入元素比当前有序序列中的所有元素都小(while循环结束后到此)
}
}
template<typename Elemtype>
void MyArray<Elemtype>::Shell_sort()
{
int gap = size / 2;
while (gap > 0) //对于gap的都要插入排序
{
for (int i = 0; i < size - gap; ++i)
{
int end = i;
Elemtype temp = arr[end + gap];
while (end >= 0)
{
if (arr[end] > temp)
{
arr[end + gap] = arr[end];
end -= gap;
}
else
{
break;
}
}
arr[end + gap] = temp;
}
gap /= 2;
}
}
template<typename Elemtype>
void MyArray<Elemtype>::Quick_sort(int begin, int end)
{
//只有一个数或区间不存在
if (begin >= end)
return;
int left = begin;
int right = end;
//选左边为key
int keyi = begin;
while (begin < end)
{
//右边选小 等号防止和key值相等 防止顺序begin和end越界
while (arr[end] >= arr[keyi] && begin < end)
{
--end;
}
//左边选大
while (arr[begin] <= arr[keyi] && begin < end)
{
++begin;
}
//小的换到右边,大的换到左边
Swap(&arr[begin], &arr[end]);
}
Swap(&arr[keyi], &arr[end]);
keyi = end;
//[left,keyi-1]keyi[keyi+1,right]
Quick_sort(left, keyi - 1);
Quick_sort(keyi + 1, right);
}
template<typename Elemtype>
void MyArray<Elemtype>::Radix_sort()
{
if (size <= 0)
return;
int i, j, num, tempIndex;//准备计数和下标记录
//1、准备桶子
Elemtype** tempArr = new Elemtype * [10];//动态实现二维数组
for (i = 0; i < 10; ++i)
{
tempArr[i] = new Elemtype[size];
}
//2、循环
for (int n = 1; n < 10000; n *= 10)//最外层循环 - 最大数位数
{
//2.1、桶子初始化
for (i = 0; i < 10; ++i)
{
for (j = 0; j < size; ++j)
{
//初始化给的值一定不会出现在数据当中
tempArr[i][j] = -1;
}
}
//2.2、数据入桶
for (i = 0; i < size; ++i)
{
//重点
tempIndex = (arr[i] / n) % 10;//桶子编号
tempArr[tempIndex][i] = arr[i];//入桶
}
//2.3、数据出桶
num = 0;//计数初始化
//数据取出 - 竖着遍历的
for (i = 0; i < 10; ++i)//列
{
for (j = 0; j < size; ++j)//行
{
if (tempArr[i][j] != -1)
{
arr[num++] = tempArr[i][j];
}
//不要else break;
}
}
}
}
template<typename Elemtype>
void MyArray<Elemtype>::Merge_sort(int left, int right)
{
if (left >= right)
return;
int mid = left + ((right - left) >> 1);
Merge_sort(left, mid);
Merge_sort(mid + 1, right);
Merge_in_arr(left, mid, right);
}
template<typename Elemtype>
void MyArray<Elemtype>::Merge_in_arr(int left, int mid, int right)
{
//2.1、准备辅助数组 - 三个游标 左右区间 辅助数组
int length = right - left + 1;//确定当前元素量
int* pData = new int[length];
//初始化
memset(pData, 0, sizeof(int) * length);
//游标
int low = left;//左
int hig = mid + 1;//右
int index = 0;//辅助
//2.2、合并过程 - 两个区间至少完成一个的遍历
//不清楚有多少次
while (low <= mid && hig <= right)
{
//左区间存在元素并且比右区间的小 落下
while (low <= mid && arr[low] <= arr[hig])
{
pData[index++] = arr[low++];
}
//右区间存在元素并且比左区间的小 落下
while (hig <= right && arr[hig] < arr[low])
{
pData[index++] = arr[hig++];
}
}
//出循环,这就说明区间至少有一个已经遍历完了
//2.3、剩下的部分直接拷贝过来
if (low <= mid)//左区间有剩
memmove(&pData[index], &arr[low], sizeof(int) * (mid - low + 1));
if (hig <= right)//右区间有剩
memmove(&pData[index], &arr[hig], sizeof(int) * (right - hig + 1));
//3、把辅助数组里面的数据拷贝给原数组
memmove(&arr[left], pData, length * sizeof(int));
delete[] pData;//过河拆桥
pData = nullptr;
}
template<typename Elemtype>
Elemtype MyArray<Elemtype>::Binary_search(Elemtype data)
{
int left = 0, right = size - 1, mid;
while (left <= right)
{
mid = left + ((right - left) >> 1);
if (data == arr[mid]) return mid;
if (data > arr[mid]) left = mid + 1;
if (data < arr[mid]) right = mid - 1;
}
return -1;
}
主函数测试
#include <iostream>
#include "MySort_vector.hpp"
#define T int //可以修改模板类型
int main() {
T a;
std::cin >> a;
MyArray<T> Arr(a);
Arr.Array_init();
//Arr.Bubble_sort();
//Arr.Select_sort();
//Arr.Insert_sort();
//Arr.Shell_sort();
//Arr.Quick_sort(0,a-1);
//Arr.Radix_sort();
Arr.Merge_sort(0, a - 1);
Arr.show();
std::cout << Arr.Binary_search(4) << std::endl;
return 0;
}