数据结构算法之归并排序

#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <cstdlib>
#include <cmath>
using namespace std;
void merge(int* a, int low, int mid, int hight)  //合并函数
{
    int* b = new int[hight - low + 1];  //用 new 申请一个辅助函数
    int i = low, j = mid + 1, k = 0;    // k为 b 数组的小标
    while (i <= mid && j <= hight)  
    {
        if (a[i] <= a[j])
        {
            b[k++] = a[i++];  //按从小到大存放在 b 数组里面
        }
        else
        {
            b[k++] = a[j++];
        }
    }
    while (i <= mid)  // j 序列结束,将剩余的 i 序列补充在 b 数组中 
    {
        b[k++] = a[i++];
    }
    while (j <= hight)// i 序列结束,将剩余的 j 序列补充在 b 数组中 
    {
        b[k++] = a[j++];
    }
    k = 0;  //从小标为 0 开始传送
    for (int i = low; i <= hight; i++)  //将 b 数组的值传递给数组 a
    {
        a[i] = b[k++];
    }
    delete[]b;     // 辅助数组用完后,将其的空间进行释放(销毁)
}
void mergesort(int* a, int low, int hight) //归并排序
{
    if (low < hight)
    {
        int mid = (low + hight) / 2;
        mergesort(a, low, mid);          //对 a[low,mid]进行排序
        mergesort(a, mid + 1, hight);    //对 a[mid+1,hight]进行排序
        merge(a, low, mid, hight);       //进行合并操作
    }
}
int main()
{
    int n, a[100];
    cout << "请输入数列中的元素个数 n 为:" << endl;
    cin >> n;
    cout << "请依次输入数列中的元素:" << endl;
    for (int i = 0; i < n; i++)
    {
        cin >> a[i];
    }
    mergesort(a, 0, n-1);
    cout << "归并排序结果" << endl;
    for (int i = 0; i < n; i++)
    {
        cout << a[i] << " ";
    }
    cout << endl;
    return 0;
}

逆序列对数求解

有一个长度为 n 的数组 求该序列的逆序对个数。

输入格式:

第一行,一个数 n,表示序列中有 n个数
第二行 n 个数,表示给定的序列,序列中每个数字不超过 1e9

输出格式:

输出序列中逆序对的数目。

输入样例:

6
5 4 2 6 3 1

 

#include<iostream>

using namespace std;

const int N=100010;
int q[N],t[N],n;
int res;//假如按照逆序对最多的情况,也就是倒序,例:5 4 3 2 1。


void merge_sort(int l,int r)
{
    if(l>=r) return;
    
    int mid=int (l+r)/2;
    merge_sort(l,mid),merge_sort(mid+1,r);//  “分”
    
    int k=0,i=l,j=mid+1;
    while(i<=mid&&j<=r)
    {
        if(q[i]<=q[j]) t[k++]=q[i++];
        else
        {
            t[k++]=q[j++];
            res+=mid-i+1;//  “治”
        }    
    }
    while(i<=mid) t[k++]=q[i++];//收尾:假如左端或者右端先填完了,得把另一端的数都加上。
    while(j<=r) t[k++]=q[j++];
    
    for(i=l,j=0;i<=r;i++,j++) q[i]=t[j];
}

int main()
{
    cin >> n;
    for(int i=0;i<n;i++) cin >> q[i];
    
    merge_sort(0,n-1);
    cout << res << endl;
    
    return 0;
}
 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值