疑问
- 是否需要考虑给出的最后一个排序是否就是排好序的,那么就不需要再进行排序了?
不需要,因为那样两种排序都是的啦。。。
代码
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn = 110;
int heap[maxn];
int insert[maxn];
//存放题中的中间数组
int sorted[maxn];
int n;
//代表是否为堆排序
int flag;
void downAdjust(int low,int high){
int i = low;
int j = i * 2;//使用左孩子,不要使用右孩子!!!
while(j <= high){//保持在堆内
if(j+1<= high && heap[j+1]>heap[j]){
j = j+1;
}
if(heap[j]>heap[i]){
swap(heap[j],heap[i]);
i = j;
j = i*2;
}else{
break;
}
}
}
void createHeap(){
for(int i=n/2;i>=1;i--){
downAdjust(i,n);
}
}
void heapSort(){ //不需要传参
createHeap(); //不需要传参
for(int i=n;i>1;i--){
swap(heap[i],heap[1]);
downAdjust(1,i-1); //这是一次堆排序了
if(flag == true){
break;
}
for(int j=1;j<=n;j++){
if(sorted[j] != heap[j]){
flag = false;
break;
}else{
flag = true;
}
}
}
}
void insertSort(){
for(int i=2;i<=n;i++){
int j;
for(j=1;j<=i-1;j++){
if(insert[i] < insert[j]){
break;
}
}
int temp = insert[i];
for(int k=i-1;k>=j;k--){
insert[k+1] = insert[k];
}
insert[j] = temp;
if(flag == true){
break;
}
for(int j=1;j<=n;j++){
if(sorted[j] != insert[j]){
flag = false;
break;
}else{
flag = true;
}
}
}
}
int main(){
flag = false;
scanf("%d",&n);
for(int i=1;i<=n;i++){
int temp;
scanf("%d",&temp);
heap[i] = temp;
insert[i] = temp;
}
for(int i=1;i<=n;i++){
scanf("%d",&sorted[i]);
}
//我们使用堆排序作为参考标准
heapSort();
if(flag == true){
printf("Heap Sort\n");
for(int i=1;i<=n;i++){
printf("%d%c",heap[i],i!=n?' ':NULL);
}
}else{
printf("Insertion Sort\n");
insertSort();
for(int i=1;i<=n;i++){
printf("%d%c",insert[i],i!=n?' ':NULL);
}
}
return 0;
}
反思
- 居然忘记
insertSort()
是什么了,我。。。太菜了,我怎么可以去读研呢。。。 - 要清楚
void downAdjust(int low,int high)
设置high
,而不是直接是数组大小n
是有原因的,不然你在堆排序的时候就会弄错,我就错了。。。 - 我好菜。。。
二刷代码
二刷使用的是先判断插入排序!
//暴力遍历进行判断
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 200;
int data[maxn];
int cur[maxn];
int next[maxn];
int n;
bool judgeInsert(){
bool flag = false;
for(int i=1;i<n;i++){//枚举需要插入的点
for(int j=i;j>=1;j--){
if(data[j-1]>data[j]){
swap(data[j-1],data[j]);
}else{
break;//代表找到位置了
}
}
if(flag == true){//说明这是需要的结果
return true;
}
//一轮结束进行判断
bool tmpflag=true;
for(int k=0;k<n;k++){
if(data[k]!=cur[k]){
tmpflag = false;
break;
}
}
if(tmpflag==true){
flag = true;
}
}
return false;
}
void downAdjust(int low,int high){
int i=low,j=low*2;//表示最开始的比较
while(j<=high){
//如果有右孩子并且右孩子还大
if(j+1<=high&&cur[j]<cur[j+1]){
j=j+1;
}
if(cur[i]<cur[j]){
swap(cur[i],cur[j]);
i=j;
j=i*2;
}else{
return;
}
}
return;
}
int main(){
scanf("%d",&n);
for(int i=0;i<n;i++){
scanf("%d",&data[i]);
}
for(int i=0;i<n;i++){
scanf("%d",&cur[i]);
}
//判断是否是插入排序
if(judgeInsert()){//如果是插入排序
cout<<"Insertion Sort"<<endl;
//进行输出
for(int i=0;i<n;i++){
printf("%d%c",data[i],i==n-1?NULL:' ');
}
}else{
cout<<"Heap Sort"<<endl;
//需要找到downAdjust的范围
//首先给数组移一下位置
for(int i=n;i>=1;i--){
cur[i]=cur[i-1];
}
//确定位置
int curTop = cur[1];
int pos=n;
for(;pos>=1;pos--){
if(cur[pos]<curTop){
break;
}
}
swap(cur[1],cur[pos]);
downAdjust(1,pos-1);
//进行输出
for(int i=1;i<=n;i++){
printf("%d%c",cur[i],i==n?NULL:' ');
}
}
return 0;
}