BFPRT 알고리즘 및 python 구현

2235 단어 데이터 구조
from mergeSort_recursion import mergesort
import random

def partion(a, m, m_index):
	# a    ,   m      m  , m      m  
	#  :m_index(m a  index)
	#  m  , m         ,  m      index
	
	# m            ,                 m     
	#      
	tmp = a[0]
	a[0] = m
	a[m_index] = tmp

	i = 0
	j = len(a)-1
	control_m = a[0]
	while i < j:
		while i< j and a[j] >= control_m:
			j -= 1

		a[i] = a[j]

		while i < j and a[i] <= control_m:
			i += 1
		a[j] = a[i]

	#  i = j, a[i]               
	a[i] = control_m
	print("m:{},after partion, a:{}".format(m, a))

	return i, len(a)-i-1, i


def bfprt(a, k):
	#  a  k    

	if len(a) < 5:
		#      5  ,    index k-1  ,   k    
		#                 ,         ,           
		mergesort(a,0, len(a)-1)
		return a[k-1]

	total_num = len(a)
	splits = total_num//5   #        

	#           
	split_medians = []
	for i in range(splits):
		cur = mergesort(a[i*5:(i+1)*5],0, 4)
		mid = cur[2]
		split_medians.append(mid)

	#    bfprt  ,         splits//2    ,          
	m = bfprt(split_medians, splits//2)
	#  m a  index
	m_index = [i for i in range(total_num) if a[i] == m][0]

	#  m a    ,     
	#num1, num2:  m      ,   m     
	num1, num2, m_index = partion(a, m, m_index)
	if k == num1+1:
		return m
	elif k <= num1:
		#   s1   
		return bfprt(a[:m_index], k)
	else:
		return bfprt(a[m_index+1:], k-1-m_index)


a = [5, 3, 1, 8, 2,10, 15, 18, 11,13, 16, 17, 12, 19, 0, 6, 4, 7, 9, 14]
random.shuffle(a)
k = 3
print(bfprt(a,7))

BFPRT 알고리즘 전체 사상:
1. 모든 n 개의 데 이 터 를 n / 5 (의 아래로 추출) 그룹 으로 나 누고 각 그룹 에 5 개의 요소 가 있 으 며, 병합 / 빠 른 정렬 로 각 그룹의 중위 수 (시간 복잡 도 * 5log 5 * n / 5, 즉 O (n) 를 구하 고, 재 귀적 으로 BFPRT 알고리즘 을 호출 하여 n / 5 개의 중위 수 (T (n / 5), 즉 n / 10 대 요 소 를 m 로 기록 하여 원 배열 에 있 는 m 의 위치 index (O (n) 를 찾 습 니 다.。
2. 원수 조 를 m 를 분계 점 으로 하고 m 보다 큰 num 2 개 원 소 를 m 오른쪽 에 놓 고 m 보다 작은 num 1 개 원 소 를 m 왼쪽 에 놓 습 니 다. 이때 m 의 새로운 위 치 는 index 입 니 다.new
        m 의 적당 한 위 치 를 찾기 전에 m 와 첫 번 째 요소 의 위 치 를 바 꿔 야 합 니 다.!!
3. k 와 num 1 을 비교 하면 k = num1 + 1 은 분계 점 m 가 바로 k 번 째 큰 요소 임 을 나타 낸다. 만약 에 k < = num 1 은 k 번 째 큰 요소 가 m 왼쪽 에 있다 는 것 을 나타 내 고 그 다음 에 m 왼쪽으로 가서 찾는다.그렇지 않 으 면 m 오른쪽 에서 m 오른쪽 에서 찾 아야 합 니 다.이렇게 해서 원래 의 문 제 를 규모 가 더 작은 문제 로 바 꾸 었 다.

좋은 웹페이지 즐겨찾기