第三章:查詢與排序(下)----------- 3.14 逆序對個數

Curtis_發表於2019-03-10

逆序對個數:一個數列,如果左邊的數大,右邊的數小,則稱這兩個數為一個逆序對。求出一個數列中有多少個逆序對。

 PS:學會畫示意圖,輔助思考。

 假設陣列的兩段分別有序,藉助一個輔助陣列來快取原陣列,用歸併的思路將元素從輔助陣列拷貝回原陣列。

 

#include<iostream>
using namespace std;

int nixu=0;

void merge(int arr[],int p,int mid,int r){
	
	int len=r-p+1;
	int helper[len];
	//拷貝到輔助空間的相同位置
	for(int i=0;i<len;i++){
		helper[i]=arr[i];
	} 
	
	//輔助陣列的兩個指標
	int left=p,right=mid+1;
	
	//原始陣列的指標
	int current=p;
	while(left<=mid&&right<=r){
		if(helper[left]<=helper[right]){
			arr[current++]=helper[left++];
		}
		else{  //右邊小 
			arr[current++]=helper[right++];
			nixu+=mid-left+1;
		}
	} 
	
	//這樣做完後,左邊指標可能沒到頭;右邊的沒到頭也沒關係
	while(left<=mid){
		arr[current]=helper[left];
		current++;
		left++;
	} 
}

void sort(int A[],int p,int r){
	if(p<r){
		int mid=p+((r-p)>>1);
		sort(A,p,mid);//對左側排序
		sort(A,mid+1,r);//對右側排序
		merge(A,p,mid,r);//合併 
	}
}

int main(){
	int arr[]={1,7,2,9,3,5,6,8};
	int len=8;
	sort(arr,0,7);
	cout<<nixu;
	
	return 0;
}

結果:

相關文章