排序模板
排序是很常用的东西,在我们使用sort的同时,应该也要了解几种基础排序的算法思想及实现
于是乎……RT
#include <cstdio>
#include <windows.h>
#include <algorithm> // swap();
using namespace std;
const int MAXN = 105; // 桶排不能太大
int arr[MAXN], arr2[MAXN], t[MAXN], ma = 0, mi = 1e9;
void Merge_Sort(int s, int e) { // 归并排序
// 拆分
int mid;
if(s == e) //边界
return ;
mid = (s + e) / 2;
Merge_Sort(s, mid);
Merge_Sort(mid + 1, e);
// 二路归并
int i, j, k;
i = k = s;
j = mid + 1;
// 合并其中一个
while(i <= mid && j <= e) {
if(arr[i] <= arr[j]) {
arr2[k] = arr[i];
i++;
k++;
}
else {
arr2[k] = arr[j];
j++;
k++;
}
}
// 补漏
while(i <= mid) {
arr2[k] = arr[i];
i++;
k++;
}
while(j <= e) {
arr2[k] = arr[j];
j++;
k++;
}
// 还原
for(int p = s; p <= e; p++)
arr[p] = arr2[p];
}
void Quick_Sort1(int l, int r) { // 快速排序 盗版
int mid = arr[(l + r) / 2]; //中间值
int i = l, j = r;
while(i <= j) {
while(arr[i] < mid) //第一个大于
i++;
while(arr[j] > mid) //最后一个小于
j--;
if(i <= j) {
swap(arr[i], arr[j]);
i++;
j--;
}
}
if(j > l)
Quick_Sort1(l, j); //递归左
if(i < r)
Quick_Sort1(i, r); //递归右
// 已经很快了
}
void Quick_Sort2(int l, int r) { // 快速排序 原型及优化
int i = l, j = r, k;
k = arr[l];
while (i < j) {
while (arr[j] >= k && i < j) j--;
if (i < j)
swap(arr[i], arr[j]);
while (arr[i] <= k && i < j) i++;
if (i < j)
swap(arr[i], arr[j]);
}
if (i - 1 > l)
Quick_Sort2(l, i - 1);
if (r - 1 > i)
Quick_Sort2(i + 1, r);
// 更快
}
void Bucket_Sort(int len) { // 桶排序 自带输出
for(int i = 1; i <= len; i++)
t[arr[i]]++;
for(int i = mi; i <= ma; i++)
while(t[i]) {
printf("%d ", i);
t[i]--;
}
}
void Bubble_Sort(int len) { // 冒泡排序 自带输出
for(int i = 1; i <= len - 1; i++) {
bool flag = false; //优化,如果一次都没换就结束
for(int j = 1; j <= len - i; j++) {
if(arr[j + 1] < arr[j]) { //大于则交换
swap(arr[j + 1], arr[j]);
flag = true;
}
}
if(!flag)
break;
}
for(int i = 1; i <= len; i++)
printf ("%d ", arr[i]);
}
void Select_Sort(int len) { // 选择排序 自带输出
for(int i = 1; i <= len - 1; i++) {
int index = i;
for(int j = i + 1; j <= len; j++) { //后面最小值的下标
if(arr[j] < arr[index])
index = j;
}
if(index != i)
swap(arr[i], arr[index]);
}
for(int i = 1; i <= len; i++)
printf ("%d ", arr[i]);
}
void Make_Heap(int i, int n) { // 维护堆
int c = i * 2;
while(c <= n) {
if(c + 1 <= n && arr[c] < arr[c + 1])
c++;
if(arr[i] < arr[c]) {
swap(arr[i], arr[c]);
i = c;
c *= 2;
}
else return ;
}
}
void Heap_Sort(int len) { // 堆排序
for(int i = len / 2 + 1; i >= 1; i--)
Make_Heap(i, len);
for(int i = len; i >= 1; i--) {
swap(arr[1], arr[i]);
Make_Heap(1, i - 1);
}
}
void Work() { // 输入及调用
printf("请输入待排序数列的长度:\n");
int n;
scanf ("%d", &n);
Sleep(200);
printf("请输入待排序的数列:\n");
for(int i = 1; i <= n; i++) {
scanf ("%d", &arr[i]);
if(ma < arr[i])
ma = arr[i];
if(mi > arr[i])
mi = arr[i];
}
printf("A : 选择排序\n");
printf("B : 冒泡排序\n");
printf("C : 桶排序\n");
printf("D : 快速排序 盗版\n");
printf("E : 快速排序 原型及优化\n");
printf("F : 归并排序\n");
printf("G : 堆排序\n");
char c;
printf("你想选择的排序方式是:\n");
scanf ("\n%c", &c);
system("cls");
for(int i = 1; i <= 10; i++) {
Sleep(200);
printf("*");
}
printf("\n");
printf("原数列:");
for(int i = 1; i <= n; i++)
printf("%d ", arr[i]);
printf("\n");
printf("排序后:");
if(c == 'A')
Select_Sort(n);
else if(c == 'B')
Bubble_Sort(n);
else if(c == 'C')
Bucket_Sort(n);
else if(c == 'D') {
Quick_Sort1(1, n);
for(int i = 1; i <= n; i++)
printf ("%d ", arr[i]);
}
else if(c == 'E') {
Quick_Sort2(1, n);
for(int i = 1; i <= n; i++)
printf ("%d ", arr[i]);
}
else if(c == 'F') {
Merge_Sort(1, n);
for(int i = 1; i <= n; i++)
printf ("%d ", arr[i]);
}
else if(c == 'G') {
Heap_Sort(n);
for(int i = 1; i <= n; i++)
printf ("%d ", arr[i]);
}
printf("\n\n已完成");
return ;
}
int main() {
Work();
return 0;
}