常用排序算法的C++实现
放假没事干,复习复习,有空再用python写一遍
#include<iostream>
#include<math.h>
#include<Windows.h>
#include<vector>
#include<time.h>
using namespace std;
//冒泡排序
void BubbleSort(vector<int>& vec)
{
int len = vec.size();
for (int i = 0; i < len; ++i)
{
int sorted = 1;
for (int j = len - 1; j > i; --j)
{
if (vec[j] < vec[j - 1])
{
int tmp = vec[j];
vec[j] = vec[j - 1];
vec[j - 1] = tmp;
sorted = 0;
}
}
if (sorted)
{
return;
}
}
}
//选择排序
void SelectionSort(vector<int>& vec)
{
int len = vec.size();
for (int i = 0; i < len - 1; ++i)
{
int min = i ;
for (int j = i +1; j < len; ++j)
{
if (vec[min] > vec[j])
{
min = j;
}
}
int tmp = vec[i];
vec[i] = vec[min];
vec[min] = tmp;
}
}
//简单插入排序
void InsertionSort(vector<int>& vec)
{
int len = vec.size();
for (int i = 1; i < len; ++i) //有序[0,i),插入i
{
if (vec[i] < vec[i - 1])
{
int tmp = vec[i];
int j = i - 1;
while (j >= 0 && vec[j] > tmp)
{
vec[j + 1] = vec[j];
--j;
}
vec[j + 1] = tmp;
}
}
}
//归并排序
void merge(vector<int>& vec, int le, int mi, int ri)
{
vector<int> aux(ri - le);
//[le,ri)和[mi,ri)合并
int i = le, j = mi, k = 0;
for (; i < mi && j < ri;)
{
if (vec[i] < vec[j])
{
aux[k++] = vec[i++];
}
else
{
aux[k++] = vec[j++];
}
}
while (i < mi)
{
aux[k++] = vec[i++];
}
while (j < ri)
{
aux[k++] = vec[j++];
}
k = 0;
for (int i = le; i < ri; ++i)
{
vec[i] = aux[k++];
}
}
void MergeSort(vector<int>& vec, int le, int ri)
{
if (le >= ri - 1) //只有一个元素或者没有元素不必排序
{
return;
}
//排序区间[le,ri)
int mi = le + (ri - le) / 2;
if (le < mi - 1)
{
MergeSort(vec, le, mi);
}
if (mi < ri - 1)
{
MergeSort(vec, mi, ri);
}
merge(vec, le, mi, ri);
}
void MergeSort(vector<int>& vec)
{
int len = vec.size();
MergeSort(vec, 0, len);
}
//希尔排序
void ShellSort(vector<int>& vec)
{
int len = vec.size();
if (!len)
{
return;
}
int gap = len / 3 + 1;
do
{
gap = gap / 3 + 1;
for (int i = gap; i < len; i+=gap)
{
if (vec[i - gap] > vec[i])
{
int j = i - gap;
int tmp = vec[i];
while (j >= 0 && vec[j] > tmp)
{
vec[j + gap] = vec[j];
j -= gap;
}
vec[j + gap] = tmp;
}
}
} while (gap>1);
}
//最大堆排序
void maxheap(vector<int>& vec,int root,int limit)
//对vec中小于limit内的值,将以root为根的子树调整为堆(此处为最大堆)
//且假设只有root可能不在正确的位置上,其左右子树都已经是最大堆
//默认数组起始元素下标为1,方便计算
{
int largest = root;
if (2 * root < limit && vec[largest] < vec[2 * root])
{
largest = 2 * root;
}
if (2 * root + 1 < limit && vec[largest] < vec[2 * root + 1])
{
largest = 2 * root + 1;
}
if (largest != root)
{
int tmp = vec[largest];
vec[largest] = vec[root];
vec[root] = tmp;
maxheap(vec, largest, limit);
}
}
void create_maxheap(vector<int>& vec)
{
vec.insert(vec.begin(), 0);
//vec头插个值,使待排序数列的下标从1开始
int len = vec.size();
//从后往前maxheap,这样才能满足maxheap中默认左右子树都为最大堆的假设
for (int i = len / 2; i > 0; --i)
{
maxheap(vec, i, len);
}
}
void HeapSort(vector<int>& vec)
{
create_maxheap(vec);
int len = vec.size(); //len是排序序列长加1的值!
for (int i = len - 1; i > 1; --i)
{
int tmp = vec[i];
vec[i] = vec[1];
vec[1] = tmp;
//堆顶和最末元素交换,此时最大堆性质不满足了
//再重建最大堆
maxheap(vec, 1, i);
}
}
//快速排序
void QuickSort_1(vector<int>& vec, int le, int ri)
{
//对[le,ri)排序
if (ri <= le + 1)
{
return;
}
int X = vec[le]; //基准数,先保存这个数,即先把le处挖个坑,找个数来填这里
int i = le, j = ri - 1;
while (i < j)
{
while (i < j && vec[j] > X)
{
--j;
}
if (i < j)
{
vec[i++] = vec[j]; //j的值赋给i,j处多出一个坑,下面找一个值填这个坑
}
while (i < j && vec[i] <= X)
{
++i;
}
if (i < j)
{
vec[j--] = vec[i]; //填上面j的坑,但i又多出个坑,下次循环再填这个新坑
}
}
vec[i] = X;
//i==j,即最后剩一个坑,用最开始的X来填,这样i(j)左边的都是小于X的,i(j)右边的都是大于X的
//下面再对左右子序列递归快排
QuickSort_1(vec, le, i);
QuickSort_1(vec, i + 1, ri);
}
void QuickSort_1(vector<int>& vec)
{
int len = vec.size();
QuickSort_1(vec, 0, len);
}
void QuickSort_2(vector<int>& vec,int le,int ri)
{
if (le >= ri)
{
return;
}
int X = vec[ri - 1]; //右边界值作为基准数
int i = le - 1, j = le;
for (; j < ri-1; ++j)
{
if (vec[j] < X)
{
++i;
int tmp = vec[i];
vec[i] = vec[j];
vec[j] = tmp;
}
}
int tmp = vec[i+1];
vec[i+1] = vec[j];
vec[j] = tmp;
QuickSort_2(vec, le, i+1);
QuickSort_2(vec,i + 2, ri);
}
//基数排序
void QuickSort_2(vector<int>& vec)
{
int siz = vec.size();
QuickSort_2(vec, 0, siz);
}
void BaseSort(vector<int>& vec)
{
int len = vec.size();
int max = 0;
for (int i = 0; i < len; ++i)
{
if (max < vec[i])
{
max = vec[i];
}
}
int max_digits = 0;
while (max)
{
++max_digits;
max /= 10;
}
//max_digits是待排序数列中最长的位数
vector<vector<int>> bases(10, vector<int>(len+1,0));
//每一行是一个桶,行号对应桶号,每行最后一位记录当前桶有几个元素
for (int i = 0; i < max_digits; ++i)
{
int func = int(pow(10, i));
for (int j = 0; j < len; ++j)
{
int q = vec[j] / func;
int p = q % 10;
int count = bases[p][len]; //当前行有几个元素
bases[p][count] = vec[j];
++bases[p][len];
}
//按桶号顺序依次将数据复制回原数组
int m = 0;
for (int j = 0; j < 10; ++j)
{
for (int k = 0; k < bases[j][len]; ++k)
{
vec[m++] = bases[j][k];
}
bases[j][len] = 0; //每行的计数位归零
}
}
}
//计数排序
void CountingSort(vector<int>& vec)
{
int len = vec.size();
int min = INT64_MAX, max = INT64_MIN;
for (int i = 0; i < len; ++i)
{
if (vec[i] < min)
{
min = vec[i];
}
if (vec[i] > max)
{
max = vec[i];
}
}
vector<int> temp(max - min + 1);
for (int i = 0; i < len; ++i)
{
temp[vec[i] - min] += 1;
}
for (int i = 0, j = 0; i < max - min + 1; ++i)
{
int k = 0;
while (k < temp[i])
{
++k;
vec[j++] = min + i;
}
}
}
void main()
{
srand(time(NULL));
vector<int> vec(10000);
for (int i = 0; i < 10000; ++i)
{
vec[i] = rand();
}
int t1 = GetTickCount();
BubbleSort(vec);
cout <<"冒泡:"<< GetTickCount() - t1 << "\n";
for (int i = 0; i < 10000; ++i)
{
vec[i] = rand();
}
t1 = GetTickCount();
SelectionSort(vec);
cout << "选择:"<<GetTickCount() - t1 << "\n";
for (int i = 0; i < 10000; ++i)
{
vec[i] = rand();
}
t1 = GetTickCount();
MergeSort(vec);
cout << "归并:"<<GetTickCount() - t1 << "\n";
for (int i = 0; i < 10000; ++i)
{
vec[i] = rand();
}
t1 = GetTickCount();
ShellSort(vec);
cout << "希尔:"<<GetTickCount() - t1 << "\n";
for (int i = 0; i < 10000; ++i)
{
vec[i] = rand();
}
t1 = GetTickCount();
InsertionSort(vec);
cout << "插入:"<<GetTickCount() - t1 << "\n";
for (int i = 0; i < 10000; ++i)
{
vec[i] = rand();
}
t1 = GetTickCount();
HeapSort(vec);
cout << "堆排:"<<GetTickCount() - t1 << "\n";
for (int i = 0; i < 10000; ++i)
{
vec[i] = rand();
}
t1 = GetTickCount();
BaseSort(vec);
cout << "基数:"<<GetTickCount() - t1 << "\n";
for (int i = 0; i < 10000; ++i)
{
vec[i] = rand();
}
t1 = GetTickCount();
CountingSort(vec);
cout << "计数:"<<GetTickCount() - t1 << "\n";
for (int i = 0; i < 10000; ++i)
{
vec[i] = rand();
}
t1 = GetTickCount();
QuickSort(vec);
cout <<"快排1:"<< GetTickCount() - t1<<"\n";
for (int i = 0; i < 10000; ++i)
{
vec[i] = rand();
}
t1 = GetTickCount();
QuickSort_2(vec);
cout << "快排2:"<<GetTickCount() - t1 << "\n";
}
进击的小🐴农