1.插入排序还是归并排序
解题思路:
(1)插入:前段有序,后段与初始序列一致。找到第一个破坏序列有序的下标,再继续下一轮插入排序
(2)归并:段内有序,需确定最后归并长度。从归并段为2,4,8…开始找起,看是否每段段内有序,如果其中某段不满足有序,则记下当前归并段长度,再将归并段*2即为下次归并长度。
#include <stdio.h>
#include <string.h>int Judge(int a[],int b[],int n) {//判断是插入还是归并段
int i,flag=0,pos=0;
for(i=1; i<n; i++) {
if(b[i-1]<=b[i]) {
flag=1;
} else {
pos=i;
break;
}
}
if(flag) {
for(i=pos; i<n; i++) {
if(a[i]!=b[i]) {
pos=0;
break;
}
}
} else
pos=0;
return pos;
}void NextInsertionSort(int a[],int pos,int n) {//下一次插入排序
int i,tmp=a[pos];
int index;
for(i=0; i<pos; i++) {
if(a[i]>tmp) {
index=i;
break;
}
}
for(i=pos-1; i>=index; i--) {
a[i+1]=a[i];
}
a[index]=tmp;
}int k=0;void Merge(int a[],int low,int high,int mid) {//两段归并成一段
int i,j;
int c[100]= {0};
for(i=low; i<=high; i++) {
c[i]=a[i];
}
i=low,j=mid+1;
while(i<=mid&&j<=high) {
if(c[i]<=c[j]) {
a[k++]=c[i];
i++;
} else {
a[k++]=c[j];
j++;
}
}
while(i<=mid) {
a[k++]=c[i];
i++;
}
while(j<=high) {
a[k++]=c[j];
j++;
}
}int GetMergeLen(int a[],int n) {//获得当前归并段的最大长度
int i,j;
for(j=2; j<=n; j*=2) {//j<=n
for(i=j; i<n; i=i+2*j)//i<n
{
if(a[i-1]>a[i])
break;
}
if(i<n)
break;
}
return j;
}void NextMergeSort(int a[],int low,int high,int len) {//下一次归并
int i;
for(i=low; i<=high; i+=len) {
int mid=(i+i+len-1)/2;
if(i+len-1<=high) {
Merge(a,i,i+len-1,mid);
}
else if(mid<high) {
Merge(a,i,high,mid);
}
}
}int main() {
int n;
scanf("%d",&n);
int i;
int a[n],b[n];
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
for(i=0; i<n; i++) {
scanf("%d",&a[i]);
}
for(i=0; i<n; i++) {
scanf("%d",&b[i]);
}
int pos=Judge(a,b,n);
if(pos) {
printf("Insertion Sort\n");
NextInsertionSort(b,pos,n);
} else {
printf("Merge Sort\n");
int len=2*GetMergeLen(b,n);//下一次归并段长度=当前归并段长度*2
NextMergeSort(b,0,n-1,len);
}
for(i=0; i<n; i++) {
if(i)
printf(" ");
printf("%d",b[i]);
}
return 0;
}
2.堆排序
#include<bits/stdc++.h>
using namespace std;
void HeapAdjust(int* a, int i, int n) //调整堆
{
int lchild = 2 * i; //i的左孩子节点序号
int rchild = 2 * i + 1; //i的右孩子节点序号
int max = i; //临时变量
if (i <= n / 2) { //如果i不是叶节点就不用进行调整
if (lchild <= n && a[lchild] > a[max])
max = lchild;
if (rchild <= n && a[rchild] > a[max])
max = rchild;
if (max != i) {
swap(a[i], a[max]);
HeapAdjust(a, max, n); //避免调整之后不是堆
}
}
}
void BuildHeap(int* a, int n) //建立堆
{
for (int i = n / 2; i >= 1; i--){ //非叶节点最大序号值为size/2
HeapAdjust(a, i, n);
}
}
void HeapSort(int* a, int n) //堆排序
{
BuildHeap(a, n);
for (int i = n; i > 1; i--){
swap(a[1], a[i]); //交换堆顶和最后一个元素,即每次将剩余元素中的最大者放到最后面
HeapAdjust(a, 1, i - 1); //重新调整堆顶节点成为大顶堆
for (int j = 1; j <= n; j++){
if (j == 1)
cout << a[j];
else
cout << " " << a[j];
}
cout << endl;
}
}
int main()
{
int a[100], n;
while (~scanf("%d", &n)){
for (int i = 1; i <= n; i++)
cin >> a[i];
HeapSort(a, n);
}
return 0;
}