1.推荐使用vector<int> 传引用数组不用给定大小范围....我用的int数组,麻烦还有限制,但是目前懒得改
2.引用这个还挺好用的
3.插入排序的话 前面有序,后面和原数组内容一致 我只是模拟了下插入第i个元素的最终排序 没有实现从头到尾排序的
4.归并排序注意是二路归并 直接二分往下模拟会有问题代码注释中有说明 直接sort 2的i次方的跨度往后排序 但是我没写这个
5.堆排序 最终求从小到大排序需要建立大根堆 然后逐步调整
6.由于这两个个一样 所以两个题合并了 merge直接用归并模拟有问题,注意这个问题
#include <iostream>
#include <algorithm>
using namespace std;
int n, a[100], b[100], i, j, ans[100], len=1;
bool flag=false;//merge结束条件
void InsertSort(int (&a)[100], int n) {
int tmp = a[n], j;
for(j=n-1; j>=0; j--) {
if(a[j] > tmp) {
a[j+1] = a[j];
} else break;
}
a[j+1] = tmp;
}
//下标从0开始存 一般建议从1存 A[0]用来放置标兵,左右子节点计算也方便(*/2即左 不用+1 -1之类的)..但是我现在懒得改
void AdjustHeap(int (&a)[100], int l, int r) {
int tmp = a[l];//类似于快排中的pivot 插入排序等标兵角色
for(int i=2*l+1; i<r; i=i*2+1) {
if(i+1<r && a[i]<a[i+1]) { //左子节点小于右子节点
i++;
}
if(a[i] > tmp) { //二者最大的子节点大于父节点
a[l] = a[i];//父节点有子节点赋值
l = i;//继续向下
} else break;
}
a[l] = tmp;
}
void HeapSort(int (&a)[100], int l, int r) {
//构建大根堆
for(int i=r/2-1; i>=0; i++) {
AdjustHeap(a, i, r);
}
//排序 大的逐步交换到最后 相当于小-》大排序
for(int i=r-1; i>0; i--) {
swap(a[0], a[i]);
AdjustHeap(a, 0, i); //i之后的都排好了
}
}
void Merge(int (&a)[100], int l, int r, int m) {
int i=l, temp[100];
int j=m+1;
int k=l;
int sum;//求逆序对数
while(i<=m&&j<=r) {
if(a[i]>a[j]) {
sum+=m-i+1;
temp[k++]=a[j++];
} else {
temp[k++]=a[i++];
}
}
while(i<=m) {
temp[k++]=a[i++];
}
while(j<=r) {
temp[k++]=a[j++];
}
for(i=l; i<=r; i++) {
a[i]=temp[i];
// cout << a[i] << " ";
}
//cout << endl;
}
void MergeSort(int (&a)[100], int l, int r) {
int i;
cout << l << " " << r << endl;
if(l < r) {
int mid = (l+r)/2;
MergeSort(a, l, mid);
MergeSort(a, mid+1, r);
Merge(a, l, r, mid);
for(i=0; i<n; i++) {
cout << a[i] << " ";
//if(a[i] != b[i])
// break;
}
cout << i<< endl;
if(i==n) {//下一次 结束
cout << l << " " << r << endl;
}
}
}
int main() {
cin >> n;
for (int i = 0; i < n; i++)
cin >> a[i];
for (int i = 0; i < n; i++)
cin >> b[i];
i=0;
while(i<n-1&&b[i] <= b[i + 1])
i++;
int j=i+1 ;
while(a[j] == b[j] && j < n)
j++;
if (j == n) {
cout << "Insertion Sort\n";
InsertSort(b, i+1);
} else {//模拟归并排序过程
cout << "Heap Sort\n";
/*
//mergesort实际有问题 因为题目给的是二路归并排序 实际算法实现的是不断二分然后排序 比如给你6个数二路归并是1-2 3-4 5-6 然后呢第二趟是1-4 5-6 最后是1-6 但是实际算法实现是1-2 3 4-5 6 然后 1-3 4-6 最后1-6
//如果可以二分模拟的话,我的思路是先找到符合的那一趟,然后下一趟理论上是这一趟跨度的2倍 根据这个合并已知数组b的
MergeSort(a, 0, n-1);
cout << len << endl;
for(i=0; i<n; i+=2*len) {
Merge(b, i, i+2*len-1, i+len);
}
Merge(b, i, n-1, (i+n)/2);
*/
int idx = n-1;
while(idx>0 && b[idx] >= b[0]) idx--;
swap(b[0], b[idx]);
// downAdjust(b, 0, idx);
AdjustHeap(b, 0, idx);
}
for (j = 0; j < n; j++) {
if (j != 0) printf(" ");
printf("%d", b[j]);
}
return 0;
}