排序算法写了几遍,总是过段时间就忘,故在此汇总下。
写排序算法重要的是理解它的原理,找到如何遍历及遍历和终止的条件
插入排序
从左建立有序区,将右侧的值依次插入该有序区,有序区中从插入的位置开始依次后移一位;从左往右遍历
void InsertSort(std::vector<int>& datas)
{
//等待排序区间,插入到有序区
for(size_t i = 1; i < datas.size(); ++i)
{
//有序区间
for(size_t j = 0; j < i; ++j)
{
//按从小到大的顺序,遇到第一个比他小的值即终止,依次后移
if(datas[i] < datas[j])
{
int value = datas[i];
for(size_t k = i; k > j; --k)
datas[k] = datas[k-1];
datas[j] = value;
break;
}
}
}
}
冒泡排序
从左到右相邻的数依次比较,值最大或最小的依次冒出;从右往左遍历
void BubbleSort(std::vector<int>& datas)
{
//当前需排序的值
for(size_t i = datas.size(); i > 0 ; --i)
{
//从第一个位置开始,依次冒出相邻两个数
for(size_t j = 0; j < i-1; ++j)
{
if(datas[j] > datas[j+1])
{
datas[j] += datas[j+1];
datas[j+1] = datas[j] - datas[j+1];
datas[j] -= datas[j+1];
}
}
}
}
选择排序
从第一个位置起,依次选择出该位置到结束的最小或最大值,放在当前位置
void SelectSort(std::vector<int>& datas)
{
for(size_t i = 0; i < datas.size(); ++i)
{
for(size_t j = i+1; j < datas.size(); ++j)
{
if(datas[i] > datas[j])
{
datas[i] ^= datas[j];
datas[j] ^= datas[i];
datas[i] ^= datas[j];
}
}
}
}
归并排序
两两比较排序;以2的倍数逐渐归并
void MergeSort(std::vector<int>& datas)
{
//两两比较一次
for(size_t i = 0; i+1 < datas.size(); i+=2)
{
if(datas[i] > datas[i+1])
{
int value = datas[i];
datas[i] = datas[i+1];
datas[i+1] = value;
}
}
std::vector<int> *new_datas = new std::vector<int>();
new_datas->assign(datas.size(), 0);
//逐渐归并,每次归并的大小,2,4,8,16...
for(size_t gap = 2; gap < datas.size(); gap*=2)
{
//当gap=2时:1,2与3,4归并; 5,6与7,8归并 至结束
int assign_idx =0;
for(size_t idx = 0; idx+gap < datas.size(); idx+=2*gap)
{
size_t i = 0;
size_t j = 0;
//归并时依次选择较小的数
while(i < gap && j < gap && idx+gap+j < datas.size())
{
if(datas[idx+i] < datas[idx+gap+j])
(*new_datas)[assign_idx++] = datas[idx+(i++)];
else
(*new_datas)[assign_idx++] = datas[idx+gap+(j++)];
}
if(i==gap)
{
//注意右侧的值不能越界
for(; j < gap && idx+gap+j < datas.size();)
(*new_datas)[assign_idx++] = datas[idx+gap+(j++)];
}