数据结构之排序

在这里插入图片描述

#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;
}

在这里插入图片描述

#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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值