1,插入排序
2,希尔排序
3,简单选择排序
4,冒泡排序
5,快速排序
6,归并排序
7,堆排序
8,还有基数排序,较为简单
#include<iostream>
#include<vector>
using namespace std;
//1,插入排序
void insertSort(vector<int>&a){
for (int i = 1; i < a.size(); i++) {//插入排序,处理第i个数据
for (int j = i - 1; j >=0; j--) {//对于第i个数据,向前插入
if (a[j] > a[j+1]) {
int temp = a[j];
a[j] = a[j+1];
a[j+1] = temp;
}
}
}
}
//2,希尔排序
void Xier(vector<int>&a){
int n = a.size();
for (int d = n / 2; d > 0; d = d / 2){//更改步长
for (int i = 0; i <d; i++){//处理每一组
for (int j = i+d; j < n; j = j + d){//处理该组的每一个数据,从每一组的第二个数数据开始处理
for (int k = j - d; k >= 0; k = k -d){
if (a[k+d] < a[k]){
int temp = a[k+d];
a[k+d] = a[k];
a[k] = temp;
}
}
}
}
}
}
//3,简单选择排序
void simpleSelect(vector<int>& a) {
for (int i = 0; i <a.size() ; i++){
int min = a[i];
for (int j = i; j < a.size(); j++) {
if (a[j] < min) {
int temp = a[j];
a[j] = a[i];
a[i] = temp;
}
}
}
}
//4,冒泡排序
void bubble(vector<int>& a) {
for (int i = 0; i < a.size(); i++) {//得到第i+1大的数据
for (int j = 1; j < a.size() - i; j++){
if (a[j] < a[j-1]){//和临近元素比较
int temp = a[j-1];
a[j-1] = a[j];
a[j] = temp;
}
}
}
}
//5,快速排序
int Partition(vector<int>&a, int low, int high)
{
int pivot = a[low];//第一个元素作为枢轴
while (low < high) {//用low,high搜索枢轴的最终位置
while (low < high && a[high] >= pivot) --high;
a[low] = a[high];//比枢轴小的元素移动到左边
while (low < high && a[low] <= pivot) ++low;
a[high] = a[low];//比枢轴大的元素移动到右端
}
a[low] = pivot;//枢轴元素存放到最终位置
return low;//返回存放枢轴的最终位置
}
void quickSort(vector<int> &a,int low,int high) {
if (low < high) {//递归跳出条件
int pivotpos = Partition(a, low, high);//划分
quickSort(a, low, pivotpos - 1);//划分左子表
quickSort(a, pivotpos + 1, high);//划分右子表
}
}
//6,堆排序,注意数组第一个元素不存元素,即数组长度为n+1,元素个数为n,a[1]--a[n]存储了n个元素
void HeadAdjust(vector<int>& a, int k, int n);
void BuildMaxHeap(vector<int>& a){//建立大根堆
int n = a.size()-1;
for (int i = n / 2; i > 0; i--)
HeadAdjust(a, i, n);
}
void HeadAdjust(vector<int>& a, int k, int n) {//将以k为根的结点调整为小根堆,n代表数组a的元素个数
a[0] = a[k];
for (int i = 2 * k; i <= n; i = 2 * i) {
if (i < n && a[i+1] > a[i]) i++;//找到较大的儿子
if (a[0] >= a[i])break;
else {
a[k] = a[i];//如果较小的儿子比父更小,将小儿子放双亲位置,再调整以小儿子原先位置为根的树
k = i;
}
}
a[k] = a[0];
}
void HeapSort(vector<int>&a) {
int n = a.size() - 1;
BuildMaxHeap(a);
for (int i = n; i > 1; i--) {
//1)堆顶和堆底元素互换
int temp = a[1];
a[1] = a[i];
a[i] = temp;
HeadAdjust(a, 1, i - 1);
}
}
//7,归并排序
void Merge(vector<int>&arr, int low, int mid, int high) {
//low为第1有序区的第1个元素,i指向第1个元素, mid为第1有序区的最后1个元素
int i = low, j = mid + 1, k = 0; //mid+1为第2有序区第1个元素,j指向第1个元素
int* temp = new int[high - low + 1]; //temp数组暂存合并的有序序列,辅助数组
if (!temp) { //内存分配失败
cout << "error";
return;
}
while (i <= mid && j <= high) {
if (arr[i] <= arr[j]) //较小的先存入temp中
temp[k++] = arr[i++];
else
temp[k++] = arr[j++];
}
while (i <= mid)//若比较完之后,第一个有序区仍有剩余,则直接复制到t数组中
temp[k++] = arr[i++];
while (j <= high)//同上
temp[k++] = arr[j++];
for (i = low, k = 0; i <= high; i++, k++)//将排好序的存回arr中low到high这区间
arr[i] = temp[k];
delete[]temp;//删除指针,由于指向的是数组,必须用delete []
}
//用递归应用二路归并函数实现排序——分治法
void MergeSort(vector<int>&arr, int low, int high) {
if (low < high) {
int mid = (low + high) / 2;
MergeSort(arr, low, mid);
MergeSort(arr, mid + 1, high);
Merge(arr, low, mid, high);
}
}
void output(vector<int> a)
{
for (int i = 0; i < a.size(); i++)
{
cout << a[i] << ' ';
}
cout << endl;
}
// 4 6 1 4 9 24 43 47 7 43
int main()
{
vector<int> in;
for (int i = 0; i < 10; i++)
{
int k;
cin >> k;
in.push_back(k);
}
//1,插入排序
insertSort(in);
cout << "插入排序" << endl;
output(in);
//2,希尔排序
Xier(in);
cout << "希尔排序" << endl;
output(in);
3,简单选择排序
simpleSelect(in);
cout << "简单选择排序" << endl;
output(in);
//4,冒泡排序
bubble(in);
cout << "冒泡排序" << endl;
output(in);
//5,快速排序
quickSort(in, 0, 9);
cout << "快速排序" << endl;
output(in);
//6,归并排序
MergeSort(in, 0, 9);
cout << "归并排序" << endl;
output(in);
//7,堆排序
HeapSort(in);
cout << "堆排序,注意这里是建立了大根堆,堆排序以后顺序输出成了递增序列,只处理的是a[1]到a[9]" << endl;
output(in);
}
补充:基数排序
情景:判断时间早晚。时间格式——时:分:秒
思路:可以看出时间格式的权重顺序应该是秒,分,时。先设置一个60容量的秒队列,将要排序的元素放到对应的位中;然后再依次收集;再将收集到的元素放到60容量的分队列中。再依次收集;最后将收集到的元素依次放到24容量的小时队列中,再依次收集得到顺序时间序列。