設 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...