運用BIT處理氣泡排序的交換次數問題

2021-08-07 05:51:54 字數 764 閱讀 2548

題意:給定乙個1~n的排列a0,a1,a2,.....,a(n-1),求對這個數列進行氣泡排序所需要的交換次數。

在資料較大時,用常規的雙重for迴圈來求解交換次數就會因為複雜度太高而存在tle的情況,所以可以利用樹狀陣列善於查詢兩個數之間的數字和的優勢進行解題。

首相樹狀陣列的基本操作就是bit的求和以及bit的值的更新,那麼如何要在沒有if語句比較的情況下進行前後數值大小的比較進而求出交換次數和,首相應該了解交換的次數和即為陣列中存在的iarray[j]的逆序樹對的和,所以對於每個位置的數array[i]只要能夠求出其之前存在的大於這個數的個數即可,而在陣列中兩個數在不滿足i以陣列array[9]=為例,用sum(array[i])函式求出在在這次操作之前i位置前有多少個比array[i]要小的數,即非逆序數,再用add(array[i],1)函式在i位置後面說明該位置之前已有多少比這個數要小的數的個數,經過一重for迴圈即可計算出所有的i位置前的逆序樹,相加和即為氣泡排序需要交換的交換次數。每次進行sum和add操作的負複雜度為o(log n),所以該方法的複雜度為o(n*log n)。注意:bit中的下標表示的是array陣列中的元素值,所以在陣列元素少或者元素的值分別為1~n中的整數,則可以直接進行樹狀陣列bit的建立,不然需要先將陣列元素值進行離散化來達到符合題目限制條件。

體悟:樹狀陣列利用位置特性做到了不用if語句比較前後數值大小而求出了交換次數,在演算法的複雜度上也較樸素演算法有大的提公升。這主要是依賴於樹狀陣列的善於計算區間數值和做到的。樹狀陣列使用的難點主要還是用的次數太少,寫起**來不足夠熟練,還以還是應該通過訓練來解決這一問題。

氣泡排序的交換次數 樹狀陣列

計算氣泡排序的交換次數 逆序數概念 在乙個排列中,如果一對數的前後位置與大小順序相反,即前面的數大於後面的數,那麼它們就稱為乙個逆序 乙個排列中所有逆序個數總和叫做這個排列的逆序數。所以氣泡排序結束即是所有的逆序數為0 思路 暴力 我們要計算逆序數,即使要統計出該值位置之前有多少個數比他大.我們用 ...

氣泡排序中資料交換的次數

problem description 聽說過氣泡排序麼?一種很暴力的排序方法。今天我們不希望你用它來排序,而是希望你能算出從小到大氣泡排序的過程中一共進行了多少次資料交換。input 輸入資料的第一行為乙個正整數 t 表示有 t 組測試資料。接下來t行,每行第乙個整數n,然後有n個整數,無序。0o...

鍊錶的氣泡排序(節點交換法)

鍊錶氣泡排序,可以通過修改節點值和交換節點兩種方法,下面給出交換節點的方法。include includestruct node int createlist node p,int i int pop sort node p int main free ph ph null return 0 int...