統計逆序對的個數,並輸出具體的逆序對(分治算法)

要求: 借鑑歸併排序的算法,在歸併的過程中,統計逆序對的個數,並記錄下具體的逆序對。設計一個分治算法,並用C/C++語言實現編程。

#include "stdio.h"
int count=0;
void Merge(int r[],int r1[],int s,int m,int t)	// 合併子序列
{
	int i=s,j=m+1,k=s;
	int b;
	while(i<=m && j<=t){
		if(r[i]<=r[j]){       // 取較小者放入r1[k]中
			r1[k++]=r[i++];
		}
		else{                 	
			count+=m-i+1;	// 若左邊數大於右邊數,則左邊數及其後邊數都大於該右邊數		
			b=i;              
			while(b<=m){
				printf("[%d,%d]\n",r[b],r[j]);
				b++;
			}
			r1[k++]=r[j++];
		}

	}
	while(i<=m)			// 若第一個子序列沒處理完,則進行收尾處理;下同
		r1[k++]=r[i++];
	while(j<=t)
		r1[k++]=r[j++];
}
void MergeSort(int r[],int s,int t){  // 對序列r[s]~r[t]進行歸併排序
	int m,r1[1000],i;
	if(s==t)
		return ;
	else{
		m=(s+t)/2;	       // 劃分
		MergeSort(r,s,m);     // 子問題1
		MergeSort(r,m+1,t);   // 子問題2
		Merge(r,r1,s,m,t);    // 合併
		for(i=s;i<=t;i++)
			r[i]=r1[i];
	}
}
int main(){
	int r[]={23,13,35,6,19,50,28,38,26,17,45},i;
	MergeSort(r,0,10);		// 三個參數分別爲待查數組、起始下標、截止下標
	for(i=0;i<=10;i++)
		printf("%d ",r[i]);
	printf("\n一共 %d個逆序對\n",count);
}

注:參考書籍 《算法設計與分析(第二版)》 王紅梅 胡明 編著

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章