bfprt演算法介紹
bfprt演算法**實現
引用自部落格:bfprt演算法o(n)解決第k小的數:在一大堆數中求其前k大或前k小的問題,簡稱top-k問題。而目前解決top-k問題最有效的演算法即是bfprt演算法,其又稱為中位數的中位數演算法,該演算法由blum、floyd、pratt、rivest、tarjan提出,最壞時間複雜度為o(n)。
我們通常會簡單地進行乙個快速排序後,得到第k個位置上的數字即可。
我們都知道的是快速排序是個不穩定的排序,它的排序過程簡單的理解主要是兩個概念partion,pivot(基準數)
一趟快速排序的過程如下:
先從序列中選取乙個數作為基準數
將比這個數大的數全部放到它的右邊,把小於或者等於它的數全部放到它的左邊
一趟快速排序也叫做partion,即將序列劃分為兩部分,一部分比基準數小,另一部分比基準數大,然後再進行分治過程,因為每一次partion不一定都能保證劃分得很均勻,所以最壞情況下的時間複雜度不能保證總是o(nlogn)的。
bfprt演算法
在bfptr演算法中,僅僅是改變了快速排序partion中的pivot值的選取,在快速排序中,我們始終選擇第乙個元素或者最後乙個元素作為pivot,而在bfptr演算法中,每次選擇五分中位數的中位數作為pivot,這樣做的目的就是使得劃分比較合理,從而避免了最壞情況的發生。
演算法步驟如下
(1)將輸入陣列的n個元素劃分為n/5組,每組5個元素,且至多只有乙個組由剩下的n%5個元素組成。
(2)尋找n/5個組中每乙個組的中位數,首先對每組的元素進行插入排序,然後從排序過的序列中選出中位數。
(3)對於(2)中找出的n/5個中位數,遞迴進行步驟(1)和(2),直到只剩下乙個數即為這n/5個元素的中位數,找到中位數後並找到對應的下標p。
(4)進行partion劃分過程,partion劃分中的pivot元素下標為p。
(5)進行高低區判斷即可。
本演算法的最壞時間複雜度為o(n),值得注意的是通過bfptr演算法將陣列按第k小(大)的元素劃分為兩部分,而
這高低兩部分不一定是有序的,通常我們也不需要求出順序,而只需要求出前k大的或者前k小的。
附上堆排序下找k小的值和bfprt演算法的**實現
public
class
code_06_bfprt
int[
] kheap =
newint
[k];
for(
int i =
0; i != k; i++
)for
(int i = k; i != arr.length; i++)}
return kheap;
}public
static
void
heapinsert
(int
arr,
int value,
int index)
else}}
public
static
void
heapify
(int
arr,
int index,
int heapsize)
if(right < heapsize && arr[right]
> arr[largest])if
(largest != index)
else
index = largest;
left = index *2+
1;right = index *2+
2;}}
// o(n)
public
static
int[
]getminknumsbybfprt
(int
arr,
int k)
int minkth =
getminkthbybfprt
(arr, k)
;int
res =
newint
[k];
int index =0;
for(
int i =
0; i != arr.length; i++)}
for(
; index != res.length; index++
)return res;
}public
static
intgetminkthbybfprt
(int
arr,
int k)
public
static
int[
]copyarray
(int
arr)
return res;
}public
static
intselect
(int
arr,
int begin,
int end,
int i)
int pivot =
medianofmedians
(arr, begin, end)
;int
pivotrange =
partition
(arr, begin, end, pivot);if
(i >= pivotrange[0]
&& i <= pivotrange[1]
)else
if(i < pivotrange[0]
)else
}public
static
intmedianofmedians
(int
arr,
int begin,
int end)
return
select
(marr,
0, marr.length -
1, marr.length /2)
;}public
static
int[
]partition
(int
arr,
int begin,
int end,
int pivotvalue)
else
if(arr[cur]
> pivotvalue)
else
}int
range =
newint[2
];range[0]
= small +1;
range[1]
= big -1;
return range;
}public
static
intgetmedian
(int
arr,
int begin,
int end)
public
static
void
insertionsort
(int
arr,
int begin,
int end)
else}}
}public
static
void
swap
(int
arr,
int index1,
int index2)
public
static
void
printarray
(int
arr)
system.out.
println()
;}public
static
void
main
(string[
] args)
;// sorted :
printarray
(getminknumsbyheap
(arr,10)
);printarray
(getminknumsbybfprt
(arr,10)
);}}
資料結構與演算法之演算法
1.乙個問題的解可以分解為幾個子問題的解 2.這個問題與分解之後的子問題,除了資料規模不同,求解思路完全一樣 3.存在遞迴終止條件 假如這裡有 n 個台階,每次你可以跨 1 個台階或者 2 個台階,請問走這 n 個台階有多少種 走法?如果有 7 個台階,你可以 2,2,2,1 這樣子上去,也可以 1...
資料結構與演算法 演算法 演算法和資料結構
資料結構與演算法 演算法 好吧,在這裡,您被優秀或優秀的軟體開發人員所隔開。在這種情況下,我會告訴您一開始或至少在我的情況下,並且我知道大多數時候,對於我認識的大多數人,您會覺得自己是乙個無能的人或白痴。基本上,我怎麼可能不理解這一點,然後您會感到沮喪。在這種情況下,我會告訴您情況並不像您想的那麼糟...
《資料結構與演算法》之資料結構簡介
資料結構 資料 結構,資料結構是計算機儲存 組織資料的方式。資料結構是指相互之間存在一種或多種特定關係的資料元素的集合。通常情況下,精心選擇的資料結構可以帶來更高的執行或者儲存效率。資料結構往往同高效的檢索演算法和索引技術有關。一 資料的邏輯結構 指反映資料元素之間的邏輯關係的資料結構,其中的邏輯關...