演算法篇 逆序對

2021-10-24 02:26:41 字數 2605 閱讀 8486

設 a 為乙個有 n 個數字的有序集 (n>1),其中所有數字各不相同。如果存在正整數 i, j使得 1 ≤ i < j ≤ n 而且 a[i] > a[j],則 這個有序對稱為 a 的乙個逆序對,也稱作逆序數

排序的過程就是消除逆序對的過程。逆序對越多,相對來說排序所需要的時間就越多。

列舉陣列元素的所有組合, 對於 長度為 n 的陣列, 一共有n(n

−1)2

\ \over 2

2n(n−1

)​種組合。

對於陣列亂序,正序和逆序三種情況,逆序反而用的時間最少, 正序次之,亂序用的時間最多。。。不知道什麼情況,按照**,有逆序對數時應該多執行乙個語句才對

int

countinversions

(int a,

int length)

}return count;

}

氣泡排序的每一次交換就會消除乙個逆序對, 交換乙個相鄰的逆序對,不會影響到其它的逆序對,所以可以計算氣泡排序在排序過程一共進行了多少次交換,由此得出陣列的逆序對數。最普通的氣泡排序和列舉的迴圈次數一樣多。但是列舉的過程沒有元素交換,會比使用氣泡排序計算逆序對數快很多。

int

countinversions_bubblesort

(int a,

int length)

} right = rightbound;

//修改範圍

for(

int i = right; i > left; i--)}

left = leftbound;

//修改範圍

}return count;

}

插入排序的每一次元素移動可以看做相鄰元素互換, 移動一次就消除乙個逆序。

所以可以用插入排序計算逆序對數,並且比用氣泡排序快。

時間複雜度為o(n

2)

\ o(n^2)

o(n2

)

int

countinversions_insertionsort

(int a,

int length)

a[j +1]

= key;

}return count;

}

乙個公升序陣列,逆序對為0。陣列中乙個連續段之間的逆序對交換,只會影響段內的逆序對數,而不會影響段外的逆序對,段外的元素與段內的元素之間的逆序對數也不受影響

將乙個陣列a從中間分成左右兩部分, 分別是a[l

eft]

...a

[mid

]和a[

mid+

1]..

.a[r

ight

]\ a[ left ]...a[mid] 和 a[mid+1]...a[right]

a[left

]...

a[mi

d]和a

[mid

+1].

..a[

righ

t]。假設兩部分分別有序,在歸併過程中,i, j 分別表示左右兩部分歸併到的元素下標, 必有i < j。如果有a[i] > a[j], 那麼左邊a[i]之後的元素也都會大於a[j], 所以a[j] 與 a[i] 到a[mid]的逆序對為 mid

−i+1

\ mid - i +1

mid−i+

1。歸併排序的兩個有序數列歸併,這兩個有序數列在陣列中是相鄰的,所以交換這兩個數列的元素,只會影響這兩個數列元素之間的逆序對數。

由此修改歸併排序來計算逆序對, 逆序對在歸併時計算。為了簡便,就使用最普通的遞迴歸併排序來說明。

int a[len]

, temp[len]

;int

mergecountinversions

(int a,

int left,

int mid,

int right)

}//拷貝回陣列a

for(

int i = left; i <= right; i++

) a[i]

= temp[i]

;return count;

}int

countinversions_mergesort

(int a,

int left,

int right)

return0;

}

樹狀陣列c, c[x] 中儲存等於x的元素的個數,初始值都為0。

倒序掃瞄數列a, 每掃瞄到乙個元素x,就在樹狀陣列c[x]上加1,表示掃瞄到的x元素個數加1。然後在樹狀陣列中查詢字首和s(x-1), 這個字首和表示小於目前已經掃瞄到的元素中,比元素x小的有多少個,因為是從後面開始掃瞄的,所以先掃瞄的元素位置比元素x的位置靠後,又比元素x小,就是逆序了。樹狀陣列的字首和就是與元素x構成逆序的元素個數。

for

(int i = n -

1; i>=

0; i--

)

演算法之逆序對

假設a 1.n 是乙個有n個不同數的陣列。若ia j 則對偶 i,j 稱為a的乙個逆序對 inversion 列出陣列的5個逆序對 由集合中的元素構成的什麼陣列具有最多的逆序對?它有多少逆序對?插入排序的執行時間與輸入陣列中的逆序對的數量有什麼關係?給出乙個求在n個元素的任何排列中逆序對數量的演算法...

演算法練習 逆序對

逆序對問題算是很經典了,最簡單的暴力破解時間複雜度o n2 時間複雜度大於o n2 的演算法是非常糟糕了,所以我們採用歸併排序的演算法改動一下,即可獲得o nlogn 的演算法。逆序對定義 數列中如果 i j arr i arr j 則arr i 和arr j 為一對逆序對。逆序對個數 privat...

演算法筆記 歸併排序 逆序對 求逆序對

洛谷p1908 逆序對 wustoj 1850 求逆序對 題目描述 1003 求逆序對 給定乙個序列a1,a2,an,如果存在iaj,那麼我們稱之為逆序對,求逆序對的數目。input 第一行為n,表示序列長度,接下來的一行包含n個整數 a1,a2,an 表示序列中的n個數。n 105,ai 1055...