日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

数据结构实验之排序五:归并求逆序数

發布時間:2024/8/23 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 数据结构实验之排序五:归并求逆序数 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題目描述

對于數列a1,a2,a3…中的任意兩個數ai,aj (i?< j),如果ai > aj,那么我們就說這兩個數構成了一個逆序對;在一個數列中逆序對的總數稱之為逆序數,如數列 1 6 3 7 2 4 9中,(6,4)是一個逆序對,同樣還有(3,2),(7,4),(6,2),(6,3)等等,你的任務是對給定的數列求出數列的逆序數。

輸入

輸入數據N(N <= 100000)表示數列中元素的個數,隨后輸入N個正整數,數字間以空格間隔。

輸出

輸出逆序數。

示例輸入

10 10 9 8 7 6 5 4 3 2 1

示例輸出

45

提示




/*歸并排序是將數列a[l,h]分成兩半a[l,mid]和a[mid+1,h]分別進行歸并排序,然后再將這兩半合并起來。
在合并的過程中(設l<=i<=mid,mid+1<=j<=h),當a[i]<=a[j]時,并不產生逆序數;當a[i]>a[j]時,在
前半部分中比a[i]大的數都比a[j]大,將a[j]放在a[i]前面的話,逆序數要加上mid+1-i。因此,可以在歸并
排序中的合并過程中計算逆序數.*/
#include <iostream>
#include<bits/stdc++.h>
using namespace std;
int tr[100001],sr[100001];//這里定義了一個暫時儲存的數組,和一個輸入數組、
long int sum;
void Merge(int s1,int e1,int s2,int e2)
{
? ? int a=s1;//第一段序列的下標
? ? int b=s2;//第二段序列的下標
? ? int c=0;//暫存數組的下標
? ? while(a<=e1&&b<=e2)// 判斷第一段和第二段取出的數哪個更小,將其存入合并序列,并繼續向下遍歷
? ? {
? ? ? ? if(sr[a]<=sr[b])
? ? ? ? ? ? tr[c++]=sr[a++];
? ? ? ? else
? ? ? ? {
? ? ? ? ? ? tr[c++]=sr[b++];
? ? ? ? ? ? sum+=e1-a+1;
? ? ? ? }//求逆序對(在有序序列中若a[i]>a[j], 則a[i]后的元素皆大于a[j])
? ? }
? ? ?while(a<=e1)// 若第一段序列還沒遍歷完,將其剩余全部復制到合并序列
? ? ? ? ? tr[c++]=sr[a++];
? ? ?while(b<=e2)// 若第二段序列還沒遍歷完,將其剩余全部復制到合并序列
? ? ? ? tr[c++]=sr[b++];
? ? ?for(int i=s1;i<=e2;i++)// 將合并序列復制到原始序列中
? ? ? ? sr[i]=tr[i-s1];
}
void merge_sort(int s,int e)
{
? ? int m;
? ? if(s<e)
? ? {
? ? ? ? m=(s+e)/2;
? ? ? ? merge_sort(s,m);//左邊有序;
? ? ? ? merge_sort(m+1,e);//右邊有序;
? ? ? ? Merge(s,m,m+1,e);//合并兩個有序序列;注意起始位置;
? ? }
}
int main()
{
? ? int n;
? ? sum=0;
? ? scanf("%d",&n);
? ? for(int i=0;i<n;i++)
? ? ? ? scanf("%d",&sr[i]);
? ? merge_sort(0,n-1);
? ? printf("%ld\n",sum);
? ? return 0;
}

總結

以上是生活随笔為你收集整理的数据结构实验之排序五:归并求逆序数的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。