#返回上一級
@author: 張海拔
@update: 2014-01-14
@link:
1/*2*author: zhanghaiba
3*date: 2014-1-15
4*file: inverse_number.c5*
6*this demo shows two method solving inverse number problem7*/
89 #include 10
#define n 512
11#define inf 0x7fffffff; //
value of sentinel
12int
array[n];
13int left_tmp[n/2+10
];14
int right_tmp[n/2+10
];15
16//
public
17int inverse_number_cnt(int *, int
);18
int inverse_number_cnt2(int *, int
);19
void merge_sort(int *, int, int, int *);
20void set_array(int *, int
);21
void show_array(int *, int
);22
2324
int main(void)25
3738
int inverse_number_cnt(int *a, int
n)39
4849
50//
modify merge_sort:
51//
add variable cnt
52//
add code "*cnt = left_len - i;"
53void merge_sort(int *a, int l, int r, int *cnt)
5474}75
}76}77
7879
int inverse_number_cnt2(int *a, int
n)80
8687
88void set_array(int *a, int
n)89
9596
97void show_array(int *a, int
n)98
逆序對的定義:序列a中,當位置i < j,而對應值a[i] > a[j],則稱(i, j)構成序列a的乙個逆序對。
解法一中,按照定義,通過兩個for迴圈即可求出逆序對數。
即以第i個的元素為起點,j從i+1開始到n-1結束按定義進行驗證,從而統計逆序對的個數,顯然i的範圍是[0, n-2]。
顯然解法一的時間複雜度是o(n^2)。
解法二的所用函式幾乎就是呼叫了乙個純粹的歸併排序,目的通過計數器cnt的位址來修改cnt,做完歸併排序後返回。
這個解法求逆序對數的原理是:對於某一次的歸併(有序表的合併),類似二叉樹的後序遍歷,歸併時當右子陣列某個元素k進入根陣列時,此時左子陣列中,下標為i的元素以及它後面的所有元素都與k構成逆序對(左子陣列的下標均《左子陣列任何乙個元素的下標,而k能進入根陣列則說明它的值比左子陣列剩下的所有元素都小,因此k的下標與上述元素的下標,均構成逆序對),所以有逆序對數要增加left_len - i,即:*cnt += left_len - i。
#返回上一級
求逆序對數目
設計乙個平均時間為o n logn o nlogn o nlog n 的演算法,在n 1 n 1000 n 1 n 1000 n 1 n 1 000 個元素的陣列中尋找逆序對數目 這裡介紹分治的思想,用歸併對陣列進行排序,在排序的過程中,即可順便將逆序對數目求出來 首先,不斷地二分這個陣列,直到最小...
求逆序對數目
題目描述 給定乙個序列 a1,a2,a na 1,a 2,a n a1 a2 an 如果存在 a i aj a i a j ai aj 且 i i j 那麼我們稱之為逆序對的,求逆序對的數目。輸入第一行為 n nn,表示序列長度,接下來的 n nn 行,第 i 1 i 1i 1 行表示序列中的第 i...
分治演算法 求逆序對數
在internet上的搜尋引擎經常需要對資訊進行比較,比如可以通過某個人對一些事物的排名來估計他對各種不同資訊的興趣,從而實現個性化服務。對於不同的排名結果可以用逆序來評價他們之間的差異。考慮1,2,n的排列i1,i2,in,如果其中存在ij,ik使得jik,那麼就稱ij,ik是這個排列的乙個逆序。...