常見排序算法模板實(shí)現(xiàn)
為了使用方便嗜诀,整理了以下幾種排序算法锥咸,沒有過的文字描述以及動畫圖表之類的說明。
#pragma once
#define NULL 0
#define MARK -65535
template<class T> //聲明
class CDaXiongTemplateSort
{
public:
CDaXiongTemplateSort();
~CDaXiongTemplateSort();
void SetMember(T*, int ); //初始化數(shù)據(jù)成員
T* BubbleSort(bool ascending = true); //冒泡排序 默認(rèn)升序
T* SelectionSort(bool ascending = true); //選擇排序
T* InsertionSort(bool ascending = true); //插入排序
T* ShellSort(bool ascending = true); //希爾排序
T* MergeSort(T*, int size, bool ascending = true); //歸并排序 start 為起始標(biāo)號,end 為結(jié)束標(biāo)號
T* BucketSort(int n); //桶排序 n表示數(shù)的位數(shù)止潮,只適用于正整數(shù)
protected:
T *m_num;
int m_length;
};
template<class T>
CDaXiongTemplateSort<T>::CDaXiongTemplateSort()
{
this->m_num = nullptr;
}
template<class T>
CDaXiongTemplateSort<T>::~CDaXiongTemplateSort()
{
if (nullptr != this->m_num)
{
delete[]this->m_num;
}
this->m_num = nullptr;
}
template<class T>
void CDaXiongTemplateSort<T>::SetMember(T* num, int length)
{
this->m_num = new T[length];
this->m_length = length;
for (int i = 0; i < length; ++i)
{
this->m_num[i] = num[i];
}
}
//冒泡
template<class T>
T* CDaXiongTemplateSort<T>::BubbleSort(bool ascending = true)
{
T tempNum;
for (int i = 0; i < this->m_length; ++i)
{
for (int j = 0; j < this->m_length - 1 - i; ++j)
{
if (ascending)
{
if (this->m_num[j] > this->m_num[j + 1])
{
tempNum = this->m_num[j];
this->m_num[j] = this->m_num[j + 1];
this->m_num[j + 1] = tempNum;
}
}
else
{
if (this->m_num[j] < this->m_num[j + 1])
{
tempNum = this->m_num[j];
this->m_num[j] = this->m_num[j + 1];
this->m_num[j + 1] = tempNum;
}
}
}
}
return this->m_num;
}
//選擇
template<class T>
T* CDaXiongTemplateSort<T>::SelectionSort(bool ascending = true)
{
T tempNum;
for (int i = 0; i < this->m_length - 1; ++i)
{
for (int j = i + 1; j < this->m_length; ++j)
{
if (ascending)
{
if (this->m_num[i] > this->m_num[j])
{
tempNum = this->m_num[j];
this->m_num[j] = this->m_num[i];
this->m_num[i] = tempNum;
}
}
else
{
if (this->m_num[i] < this->m_num[j])
{
tempNum = this->m_num[j];
this->m_num[j] = this->m_num[i];
this->m_num[i] = tempNum;
}
}
}
}
return this->m_num;
}
//插入
template<class T>
T* CDaXiongTemplateSort<T>::InsertionSort(bool ascending = true)
{
T tempNum;
int mark;
for (int i = 0; i < this->m_length - 1; ++i)
{
tempNum = this->m_num[i + 1];
for (int j = i + 1; j > 0 ; --j)
{
if (ascending)
{
if (tempNum < this->m_num[j - 1])
{
this->m_num[j] = this->m_num[j - 1];
this->m_num[j - 1] = tempNum;
}
}
else
{
if (tempNum > this->m_num[j - 1])
{
this->m_num[j] = this->m_num[j - 1];
this->m_num[j - 1] = tempNum;
}
}
}
}
return this->m_num;
}
//希爾
template<class T>
T* CDaXiongTemplateSort<T>::ShellSort(bool ascending = true)
{
T tempNum;
int step = this->m_length / 2;
while (step > 0)
{
for (int i = 0; i < this->m_length - step; ++i)
{
tempNum = this->m_num[i + step];
for (int j = i + step; j > 0 ; j-=step)
{
if (ascending)
{
if ((j - step) >= 0 && (tempNum < this->m_num[j - step])) //此處若用for循環(huán)則要判別 j - srep < 0的情況
{
this->m_num[j] = this->m_num[j - step];
this->m_num[j - step] = tempNum;
}
}
else
{
if ((j - step) >= 0 && (tempNum > this->m_num[j - step])) //此處若用for循環(huán)則要判別 j - srep < 0的情況
{
this->m_num[j] = this->m_num[j - step];
this->m_num[j - step] = tempNum;
}
}
}
}
step /= 2;
}
return this->m_num;
}
//歸并
template<class T>
T* CDaXiongTemplateSort<T>::MergeSort(T* num, int size, bool ascending = true)
{
T* lift, *right;
if (size >> 1)
{
lift = new T[size >> 1];
right = new T[size - (size >> 1)];
for (int i = 0, j = 0; i < size; ++i)
{
if (i < size >> 1)
{
lift[i] = num[i];
}
else
{
right[j++] = num[i];
}
}
MergeSort(lift, size >> 1, ascending); //排序lift
MergeSort(right, size - (size >> 1), ascending); //排序right
/**************************************************************/
/**************************************************************/
int i, j, k;
for (i = 0, j = 0, k = 0; i < size >> 1 && j < size - (size >> 1);)
{
if (ascending) //升序
{
if (lift[i] < right[j])//合并有序
{
num[k++] = lift[i++];
}
else
{
num[k++] = right[j++];
}
}
else //降序
{
if (lift[i] < right[j])//合并有序
{
num[k++] = right[j++];
}
else
{
num[k++] = lift[i++];
}
}
}
//剩余元素全部放回去
if (i >= size >> 1)//說明lift中的內(nèi)容放完了
{
while (j < size - (size >> 1))
{
num[k++] = right[j++];
}
}
else
{
while (i < size >> 1)
{
num[k++] = lift[i++];
}
}
delete[] lift;
delete[] right;
}
return num;
}
//桶
template<class T>
T* CDaXiongTemplateSort<T>::BucketSort(int n)
{
T* bucket[11]; //聲明11個桶般哼,第11個桶用來暫存有序數(shù)據(jù)
int temp; //臨時桶的下標(biāo)
static int count = 0;
for (int i = 0;i < 11; ++i)
{
bucket[i] = new T[this->m_length]; //定義10 * n 的矩陣用做存儲數(shù)據(jù) n表示需要排序數(shù)組的長度
for (int j = 0; j < this->m_length; ++j)
{
bucket[i][j] = MARK; //初始化所有桶元素
}
}
for (int i = 0, k = 1; i < n; ++i, k *= 10)//排序的次數(shù) n 最大值的位數(shù)
{
for (int j = 0; j < this->m_length; ++j)//入桶把數(shù)組this->m_num中元素全部倒入桶中
{
if (this->m_num[j] < k * 10 && this->m_num[j] >= k)
{
temp = this->m_num[j] / k % 10;
bucket[temp][j] = this->m_num[j];//放入桶中
}
}
//立刻倒回原來的數(shù)組
for (int m = 0, j = 0; m < 10; ++m)
{
for (int x = 0; x < this->m_length; ++x)//數(shù)據(jù)的個數(shù)
{
if (bucket[m][x] != MARK)
{
bucket[10][count++] = bucket[m][x];//倒回桶中
bucket[m][x] = MARK;
}
}
}
}
for (int i = 0; i < this->m_length; ++i)
{
this->m_num[i] = bucket[10][i];
}
for (int i = 0; i < 11; ++i)
{
delete []bucket[i];
bucket[i] = NULL;
}
return this->m_num;
}