代码:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
/*---------------------------改进冒泡排序------------------------------------*/
// 算法复杂度O(n^2)
vector<int> BubbleSort(vector<int> vec)
{
int length = vec.size();
bool flag = true; //避免在剩余的数已经有序的情况下做无意义的循环判断
for (int i = 0; i < length; i++)
{
flag = false;
for (int j = length - 1; j > 0;j--)
{
if (vec[j] < vec[j-1])
{
swap(vec[j], vec[j -1]);
flag = true; //如果有数据交换,则flag为true
}
}
}
return vec;
}
//简单选择排序, 算法复杂度O(n^2)
vector<int> SimpleSelectionSort(vector<int> vec)
{
int length = vec.size();
int min = 0; //保存每次找到的最小值的下标
for (int i = 0; i < length-1; i++)
{
min = i;
for (int j = i + 1; j < length; j++)
{
if (vec[j] < vec[min])
{
min = j;
}
}
if (i != min)
swap(vec[i], vec[min]);
}
return vec;
}
/*---------------------------简单插入排序------------------------------------*/
// 算法复杂度O(n^2)
vector<int> SimpleInsertSort(vector<int> vec)
{
int length = vec.size();
for (int i = 1, j = 0; i < length; i++)
{
if (vec[i] < vec[i - 1])
{
int temp = vec[i];
for (j = i - 1; j >= 0 && vec[j] > temp; j--)
{
vec[j + 1] = vec[j];
}
vec[j + 1] = temp;
}
}
return vec;
}
/*---------------------------希尔排序------------------------------------*/
//不稳定排序,算法复杂度O(n^(3/2))
vector<int> ShellSort(vector<int> vec)
{
int j = 0;
int increment = vec.size();
do
{
increment = increment / 3 + 1;
for (int i = increment; i < vec.size() ; i++)
{
if (vec[i] < vec[i - increment])
{
int temp = vec[i];
for (j = i - increment; j >= 0 && temp < vec[j];j -= increment)
{
vec[j + increment] = vec[j];
}
vec[j + increment] = temp;
}
}
} while (increment > 1);
return vec;
}
/*---------------------------堆排序------------------------------------*/
//堆排序,不稳定排序算法,时间复杂度为O(nlogn)
//不适合排序序列个数较少的情况,开始建堆所需的比较次数较多
void swap(vector<int> &temp, int head, int last) //交换堆顶与未经排序子序列的最后一个结点
{
int tmp = temp[head];
temp[head] = temp[last];
temp[last] = tmp;
}
void HeapAdjust(vector<int> &vec, int low, int high)
{
int temp = vec[low];
for (int j = low * 2; j <= high; j *= 2)
{
if (j < high && vec[j] < vec[j + 1])
j++;
if (temp >= vec[j])
break;
vec[low] = vec[j];
low = j;
}
vec[low] = temp;
}
vector<int> HeapSort(vector<int> vec)
{
vector<int> temp(vec.size() + 1, 0);
temp[0] = -1;
for (int i = 0; i < vec.size(); i++)
{
temp[i + 1] = vec[i];
}
//构建大根堆
for (int i = vec.size() / 2; i > 0; i--)
{
HeapAdjust(temp, i, vec.size());
}
//堆排序
for (int i = vec.size(); i > 1; i--)
{
swap(temp, 1, i);
HeapAdjust(temp, 1, i-1);
}
for (int i = 1; i < temp.size();i++)
{
vec[i - 1] = temp[i];
}
return vec;
}
/*---------------------------归并排序,递归实现------------------------------------*/
//合并
void Merge(vector<int>& subvec, int p, int mid, int q)
{
int a = mid - p + 1;
int b = q - mid;
vector<int> L(a + 1, 0);
vector<int> R(b + 1, 0);
for (int i = 0; i < a; i++)
L[i] = subvec[p + i];
for (int j = 0; j < b; j++)
R[j] = subvec[mid + j + 1];
L[a] = R[b] = INT_MAX;
int i = 0, j = 0;
for (int k = p; k < q + 1; k++)
{
if (L[i] <= R[j])
{
subvec[k] = L[i];
i++;
}
else
{
subvec[k] = R[j];
j++;
}
}
}
//分解
void RSort(vector<int> &subvec, int p, int q)
{
if (p < q)
{
int mid = (p + q) / 2;
RSort(subvec, p, mid);
RSort(subvec, mid + 1, q);
Merge(subvec, p, mid, q); //合并
}
}
vector<int> MergeSort(vector<int> vec)
{
int length = vec.size();
RSort(vec,0,length-1); //分解为多个子问题求解,分治思想
return vec;
}
/*---------------------------归并排序,非递归实现------------------------------------*/
//将有序的v1[i...m]和有序的v1[m+1...n]归并到有序的v2中
void Merge2(vector<int>& v1, vector<int>& v2, int i, int m, int n)
{
int k = 0, j = 0;
for (k = i, j = m + 1; i <= m && j <= n; k++)
{
if (v1[i] < v1[j])
v2[k] = v1[i++];
else
v2[k] = v1[j++];
}
if (i <= m)
{
for (int t = 0; t <= m - i; t++)
v2[k+t] = v1[i+t];
}
if (j <= n)
{
for (int t = 0; t <= n-j; t++)
v2[k+t] = v1[j+t];
}
}
//将v1中相邻长度为gap的子序列两两归并到v2中
void MergeAdjacent(vector<int>& v1, vector<int>& v2, int gap, int len)
{
int i = 0;
while (i <= len-2*gap)
{
Merge2(v1, v2, i, i + gap - 1, i + 2 * gap - 1);
i += 2 * gap;
}
if (i < len - gap + 1 ) //当不够两组进行归并时,如果剩余元素超过k个元素,仍然进行归并
Merge2(v1, v2,i, i + gap - 1, len-1);
else //如果剩余元素不超过k个元素时,直接复制给中间数组
{
for (int j = i; j < len; j++)
{
v2[j] = v1[j];
}
}
for (i = 0; i < len; i++)
v1[i] = v2[i];
}
vector<int> MergeSort2(vector<int> vec)
{
int length = vec.size();
vector<int> vec2(length, 0);
int k = 1;
while (k < length)
{
MergeAdjacent(vec, vec2, k, length);
k = 2 * k;
}
return vec;
}
/*---------------------------快速排序------------------------------------*/
int Partition(vector<int>& vec, int low, int high)
{
int pivotkey = vec[low]; //用子表中的第一个元素作为枢轴
while (low < high)
{
while (vec[high] >= pivotkey && low < high)
high--;
swap(vec[low], vec[high]);
while (vec[low] <= pivotkey && low < high)
low++;
swap(vec[low], vec[high]);
}
return low;
}
void QSort(vector<int>& vec, int low, int high)
{
int pivot;
if (low < high)
{
pivot = Partition(vec, low, high); //算出中枢值
QSort(vec, low, pivot - 1);
QSort(vec, pivot + 1, high);
}
}
vector<int> QuickSort(vector<int> vec)
{
int length = vec.size();
QSort(vec, 0, length - 1);
return vec;
}
/*---------------------------计数排序------------------------------------*/
//算法复杂度O(n),线性时间排序算法,适合于小范围的集合的排序
vector<int> CountSort(vector<int> vec)
{
int length = vec.size();
vector<int> result(length,0); //保存结果
int max; //保存最大值
//找出vec中的最大值
if (length > 0)
{
max = vec[0];
for (int i = 1; i < length; i++)
{
if (max < vec[i])
max = vec[i];
}
}
//创建保存计数的vector
vector<int> temp(max + 1, 0);
//保存最后结果
//vector<int> result;
for (int i = 0; i < length;i++)
{
temp[vec[i]] += 1;
}
//temp[i] 包含了小于等于i的个数,以确定i的位置
for (int i = 1; i <= max;i++)
{
temp[i] += temp[i - 1];
}
for (int j = length - 1; j >= 0;j--)
{
result[temp[vec[j]]-1] = vec[j];
temp[vec[j]] = temp[vec[j]] - 1;
}
return result;
}
/*---------------------------改进的计数排序------------------------------------*/
//与标准的相比,可以节约一些空间,
vector<int> CountSort2(vector<int> vec)
{
int length = vec.size();
int max; //保存最大值
//找出vec中的最大值
if (length > 0)
{
max = vec[0];
for (int i = 1; i < length; i++)
{
if (max < vec[i])
max = vec[i];
}
}
//创建保存计数的vector
vector<int> temp(max + 1, 0);
for (int i = 0; i < length; i++)
{
temp[vec[i]] += 1;
}
int j = 0;
for (int i = 0; i <= max; i++)
{
while (temp[i]--)
vec[j++] = i;
}
return vec;
}
/*---------------------------基数排序------------------------------------*/
//算法时间复杂度O(n),具有线性的时间代价
//计数排序有两种方式,LSD由数值的最右边(低位)开始,而MSD则相反,由数值的最左边开始
//LSD适用于位数少的数值,如果位数多,MSD的效率更好
/*
MSD实现是一个递归的过程:
(1)首先根据最高位的关键码K1排序,得到若干个对象组,即分到若干个桶中,每个桶中有相同的关键字
(2)再分别对每个桶根据关键码K2进行排序,再根据K2的分成若干个子桶,依次类推...
(3)最后把所有桶中的序列连接起来既构成了一个有序的序列
*/
//这里实现LSD,MSD类似
//获取x这个数的第d位的数字
//因为LSD由数值的最右边开始的,123的第1位为3,第二位为2,...
int getDigit(int x, int d)
{
int a[] = { 1, 1, 10, 100 }; //本例中,最大数是百位数,因此a[]中最大为100
return (x / a[d] % 10);
}
vector<int> RadixSortLSD(vector<int> vec)
{
int length = vec.size();
int d = 3; //本例中,最大的只有3位数
int count[10]; //每个桶排序
int j;
int* bucket = new int[length];
//对每位进行排序
for (int k = 1; k <= d; k++)
{
for (int i = 0; i < 10; i++) //利用计数排序的思想用数组模拟桶
count[i] = 0;
//统计各个桶中所盛数据个数
for (int i = 0; i < length; i++)
{
count[getDigit(vec[i], k)]++;
}
for (int i = 1; i < 10; i++)
{
count[i] += count[i - 1];
}
//这时,count[i]表示第i个桶的右边界索引
for (int i = length - 1; i >= 0; i--)
{
j = getDigit(vec[i], k);
bucket[count[j] - 1] = vec[i];
count[j]--;
}
//此时,count[i]为第i个桶的左边界
//将桶中的数据收集出来
for (int i = 0, j = 0; i < length; i++, j++)
vec[i] = bucket[j];
}
delete[] bucket;
return vec;
}
int main()
{
vector<int> array = { 9, 1, 5, 8, 3, 7, 4, 6, 2 };
vector<int> result;
//冒泡排序
result = BubbleSort(array);
cout << "冒泡排序后: ";
for (auto it = result.begin(); it != result.end(); it++)
cout << *it << " ";
cout << endl << endl;
//选择排序
result = SimpleSelectionSort(array);
cout << "简单选择排序后: ";
for (auto it = result.begin(); it != result.end(); it++)
cout << *it << " ";
cout << endl << endl;
//插入排序
result = SimpleInsertSort(array);
cout << "简单插入排序后: ";
for (auto it = result.begin(); it != result.end(); it++)
cout << *it << " ";
cout << endl << endl;
//希尔排序
result = ShellSort(array);
cout << "希尔排序后: ";
for (auto it = result.begin(); it != result.end(); it++)
cout << *it << " ";
cout << endl << endl;
//堆排序
result = HeapSort(array);
cout << "堆排序后: ";
for (auto it = result.begin(); it != result.end(); it++)
cout << *it << " ";
cout << endl << endl;
//归并排序,递归实现
result = MergeSort(array);
cout << "(递归实现)归并排序后: ";
for (auto it = result.begin(); it != result.end(); it++)
cout << *it << " ";
cout << endl<<endl;
//归并排序,非递归实现
result = MergeSort2(array);
cout << "(非递归实现)归并排序后: ";
for (auto it = result.begin(); it != result.end(); it++)
cout << *it << " ";
cout << endl << endl;
//快速排序
result = QuickSort(array);
cout << "快速排序后: ";
for (auto it = result.begin(); it != result.end(); it++)
cout << *it << " ";
cout << endl<<endl;
//计数排序
result = CountSort(array);
cout << "计数排序后: ";
for (auto it = result.begin(); it != result.end(); it++)
cout << *it << " ";
cout << endl << endl;
//计数排序2
result = CountSort2(array);
cout << "改进的计数排序后: ";
for (auto it = result.begin(); it != result.end(); it++)
cout << *it << " ";
cout << endl << endl;
//基数排序
vector<int> array2 = { 329, 457, 657, 83, 436, 720, 355, 221, 983};
cout << "基数排序前: ";
for (auto it = array2.begin(); it != array2.end(); it++)
cout << *it << " ";
cout << endl;
result = RadixSortLSD(array2);
cout << "LSD基数排序后: ";
for (auto it = result.begin(); it != result.end(); it++)
cout << *it << " ";
cout << endl << endl;
system("pause");
return 0;
}
测试: