이진 힙은 특별한 종류의 힙입니다. 이진 힙은 완전한 이진 트리(이진 트리) 또는 대략 완전한 이진 트리(이진 트리)입니다. 바이너리 힙에는 최대 힙과 최소 힙의 두 가지 유형이 있습니다. 최대 힙: 상위 노드의 키 값은 항상 하위 노드의 키 값보다 크거나 같습니다. 최소 힙: 상위 노드의 키 값은 항상 하위 노드의 키 값보다 작거나 같습니다.
우선순위 큐의 바이너리 힙 구현
이전 장에서 "선입 선출"(FIFO
)의 데이터 구조를 배웠습니다. 🎜>). "우선순위 대기열"(Queue
)이라는 대기열 변형이 있습니다. 우선순위 큐의 dequeue(Priority Queue
) 동작은 큐와 동일하며, 큐의 선두부터 dequeue된다. 그러나 우선순위 큐 내에서 요소의 순서는 "Dequeue
우선순위"에 의해 결정됩니다. 우선순위가 높은 요소는 큐의 맨 앞에 순위가 매겨지고, 우선순위가 낮은 요소는 맨 뒤에 순위가 매겨집니다. 이런 식으로 우선순위 큐의 엔큐잉() 작업은 더 복잡해지고, 우선순위에 따라 요소를 최대한 큐에 넣어야 합니다. 다음 섹션에서는 우선순위 큐가 그래프 알고리즘에 유용한 데이터 구조라는 것을 알게 될 것입니다. Enqueue
이고, 목록을 정렬하는 시간 복잡도는 O(n)
입니다. 시간 복잡성을 줄이기 위해 다른 방법을 사용할 수 있습니다. 우선순위 큐를 구현하는 전형적인 방법은 바이너리 힙(O(nlogn)
)을 사용하는 것입니다. 바이너리 힙은 Binary Heap
에서 우선순위 큐의 대기열 추가 및 대기열 제거의 복잡성을 유지할 수 있습니다. O(logn)
) )"이라고 합니다. 이 섹션에서는 최소 힙을 사용합니다. min heap
max heap
바이너리 힙의 기본 작업은 다음과 같이 정의됩니다.
- : 생성 빈 바이너리 힙 객체
BinaryHeap()
- : 힙에 새 요소 추가
insert(k)
- : 힙에서 가장 작은 요소 반환 항목, 최소 항목이 힙에 남아 있음
findMin()
- : 힙에서 최소 항목을 제거하는 동시에 힙에 있는 최소 항목을 반환합니다.
delMin()
- : 힙이 비어 있는지 여부를 반환
isEmpty()
- : 힙에 있는 노드 수를 반환
size()
- : 포함된 노드 목록에서 새 힙 생성
buildHeap(list)
아래 표시된 코드는 바이너리 힙의 예입니다. 힙에 요소를 추가하는 순서에 관계없이 매번 가장 작은 요소가 제거된다는 것을 알 수 있습니다. 다음에 이 프로세스를 구현하겠습니다.
from pythonds.trees.binheap import BinHeap bh = BinHeap() bh.insert(5) bh.insert(7) bh.insert(3) bh.insert(11) print(bh.delMin()) print(bh.delMin()) print(bh.delMin()) print(bh.delMin())
힙을 더 잘 구현하기 위해 이진 트리를 사용합니다. 우리는 항상 이진 트리의 "균형"을 유지해야 하며, 항상 로그 척도에서 작업을 유지해야 합니다. 균형 이진 트리는 루트 노드의 왼쪽 하위 트리와 오른쪽 하위 트리에 동일한 수의 하위 노드가 있습니다. 힙 구현에서는 "균형"을 대략적으로 달성하기 위해 "완전한 이진 트리" 구조를 사용합니다. 완전한 이진 트리는 각 내부 노드 트리가 최대값에 도달한다는 것을 의미합니다. 단, 마지막 레벨에는 오른쪽에 있는 여러 노드만 부족할 수 있습니다. 그림 1은 완전한 이진 트리를 보여줍니다.
그림 1: 완전 이진 트리
흥미롭게도 단일 목록으로 완전한 트리를 얻을 수 있습니다. 노드, 참조 또는 중첩 목록을 사용할 필요가 없습니다. 완전한 이진 트리의 경우 목록에 있는 노드의 첨자가 p이면 왼쪽 자식 노드의 첨자는 2p이고 오른쪽 노드는 2p+1입니다. 어떤 노드의 상위 노드를 찾으려면 Python의 정수 나누기를 직접 사용할 수 있습니다. 목록에서 노드가
색인화되면 상위 노드도 색인화됩니다. 그림 2는 완전한 이진 트리와 트리의 목록 표현을 보여줍니다. 상위 노드와 하위 노드 간의 2p 및 2p+1 관계에 유의하십시오. 완전한 트리의 목록 표현은 완전한 이진 트리의 속성을 결합하므로 간단한 수학적 방법을 사용하여 전체 트리를 효율적으로 탐색할 수 있습니다. 또한 이를 통해 바이너리 힙을 효율적으로 구현할 수 있습니다. n
n//2
힙에 요소를 저장하는 방법은 힙의 순서에 따라 다릅니다. 소위 힙 순서는 힙에 있는 임의의 노드 x에 대해 해당 상위 노드 p의 키 값이 x의 키 값보다 작거나 같다는 것을 의미합니다. 그림 2는 힙 순서 속성이 있는 완전한 이진 트리를 보여줍니다.
그림 2: 완전한 트리 및 해당 목록 표현
接下来我们来构造二叉堆。因为可以采用一个列表保存堆的数据,构造函数只需要初始化一个列表和一个 Listing 1 我们接下来要实现的是 图 3:新节点“上浮”到其正确位置 当我们让一个元素“上浮”时,我们要保证新节点与父节点以及其他兄弟节点之间的堆次序。当然,如果新节点非常小,我们仍然需要将它交换到其他层。事实上,我们需要不断交换,直到到达树的顶端。Listing 2 所示的是“上浮”方法,它把一个新节点“上浮”到其正确位置来满足堆次序。这里很好地体现了我们之前在 在Listing 3 中,我们已经可以写出 Listing 2 Listing 3 我们已经写好了 图 4:替换后的根节点下沉 为了保持堆次序,我们需将新的根节点沿着一条路径“下沉”,直到比两个子节点都小。在选择下沉路径时,如果新根节点比子节点大,那么选择较小的子节点与之交换。Listing 4 所示的是新节点下沉所需的 Listing 4 Listing 5 所示的是 Listing 5 关于二叉堆的最后一部分便是找到从无序列表生成一个“堆”的方法。我们首先想到的是,将无序列表中的每个元素依次插入到堆中。对于一个排好序的列表,我们可以用二分搜索找到合适的位置,然后在下一个位置插入这个键值到堆中,时间复杂度为 Listing 6 图 5:将列表[ 9, 6, 5, 2, 3]生成一个二叉堆 图 5 所示的是利用 下列所示的代码是完全二叉堆的实现。 能在currentSize
来表示堆当前的大小。Listing 1 所示的是构造二叉堆的 python 代码。注意到二叉堆的heaplist
并没有用到,但为了后面代码可以方便地使用整除,我们仍然保留它。class BinHeap:
def init(self):
self.heapList = [0]
self.currentSize = 0
insert
方法。首先,为了满足“完全二叉树”的性质,新键值应该添加到列表的末尾。然而新键值简单地添加在列表末尾,显然无法满足堆次序。但我们可以通过比较父节点和新加入的元素的方法来重新满足堆次序。如果新加入的元素比父节点要小,可以与父节点互换位置。图 3 所示的是一系列交换操作来使新加入元素“上浮”到正确的位置。headlist
中没有用到的元素 0 的重要性。这样只需要做简单的整除,将当前节点的下标除以 2,我们就能计算出任何节点的父节点。insert
方法的代码。insert
里面很大一部分工作是由percUp
函数完成的。当树添加新节点时,调用percUp
就可以将新节点放到正确的位置上。def percUp(self,i):
while i // 2 > 0:
if self.heapList[i] < self.heapList[i // 2]:
tmp = self.heapList[i // 2]
self.heapList[i // 2] = self.heapList[i]
self.heapList[i] = tmp
i = i // 2
def insert(self,k):
self.heapList.append(k)
self.currentSize = self.currentSize + 1
self.percUp(self.currentSize)
insert
方法,那再来看看delMin
方法。堆次序要求根节点是树中最小的元素,因此很容易找到最小项。比较困难的是移走根节点的元素后如何保持堆结构和堆次序,我们可以分两步走。首先,用最后一个节点来代替根节点。移走最后一个节点保持了堆结构的性质。这么简单的替换,还是会破坏堆次序。那么第二步,将新节点“下沉”来恢复堆次序。图 4 所示的是一系列交换操作来使新节点“下沉”到正确的位置。percDown
和minChild
方法的代码。def percDown(self,i):
while (i * 2) <= self.currentSize:
mc = self.minChild(i)
if self.heapList[i] > self.heapList[mc]:
tmp = self.heapList[i]
self.heapList[i] = self.heapList[mc]
self.heapList[mc] = tmp
i = mc
def minChild(self,i):
if i * 2 + 1 > self.currentSize:
return i * 2
else:
if self.heapList[i*2] < self.heapList[i*2+1]:
return i * 2
else:
return i * 2 + 1
delMin
操作的代码。可以看到比较麻烦的地方由一个辅助函数来处理,即percDown
。def delMin(self):
retval = self.heapList[1]
self.heapList[1] = self.heapList[self.currentSize]
self.currentSize = self.currentSize - 1
self.heapList.pop()
self.percDown(1)
return retval
O(logn)
。另外插入一个元素到列表中需要将列表的一些其他元素移动,为新节点腾出位置,时间复杂度为O(n)
。因此用insert
方法的总开销是O(nlogn)
。其实我们能直接将整个列表生成堆,将总开销控制在O(n)
。Listing 6 所示的是生成堆的操作。def buildHeap(self,alist):
i = len(alist) // 2
self.currentSize = len(alist)
self.heapList = [0] + alist[:]
while (i > 0):
self.percDown(i)
i = i - 1
buildHeap
方法将最开始的树[ 9, 6, 5, 2, 3]
中的节点移动到正确的位置时所做的交换操作。尽管我们从树中间开始,然后回溯到根节点,但percDown
方法保证了最大子节点总是“下沉”。因为堆是完全二叉树,任何在中间的节点都是叶节点,因此没有子节点。注意,当i=1
时,我们从根节点开始下沉,这就需要进行大量的交换操作。可以看到,图 5 最右边的两颗树,首先 9 从根节点的位置移走,移到下一层级之后,percDown
进一步检查它此时的子节点,保证它下降到不能再下降为止,即下降到正确的位置。然后进行第二次交换,9 和 3 的交换。由于 9 已经移到了树最底层的层级,便无法进一步交换了。比较一下列表表示法和图 5 所示的树表示法进行的一系列交换还是很有帮助的。i = 2 [0, 9, 5, 6, 2, 3]
i = 1 [0, 9, 2, 6, 5, 3]
i = 0 [0, 2, 3, 6, 5, 9]
def insert(self,k):
self.heapList.append(k)
self.currentSize = self.currentSize + 1
self.percUp(self.currentSize)
def percDown(self,i):
while (i * 2) <= self.currentSize:
mc = self.minChild(i)
if self.heapList[i] > self.heapList[mc]:
tmp = self.heapList[i]
self.heapList[i] = self.heapList[mc]
self.heapList[mc] = tmp
i = mc
def minChild(self,i):
if i * 2 + 1 > self.currentSize:
return i * 2
else:
if self.heapList[i*2] < self.heapList[i*2+1]:
return i * 2
else:
return i * 2 + 1
def delMin(self):
retval = self.heapList[1]
self.heapList[1] = self.heapList[self.currentSize]
self.currentSize = self.currentSize - 1
O(n)
的开销下能生成二叉堆看起来有点不可思议,其证明超出了本书的范围。但是,要理解用O(n)
的开销能生成堆的关键是因为logn
因子基于树的高度。而对于buildHeap
里的许多操作,树的高度比logn
要小。
위 내용은 Python에서 바이너리 힙을 구현하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

Python과 C는 각각 고유 한 장점이 있으며 선택은 프로젝트 요구 사항을 기반으로해야합니다. 1) Python은 간결한 구문 및 동적 타이핑으로 인해 빠른 개발 및 데이터 처리에 적합합니다. 2) C는 정적 타이핑 및 수동 메모리 관리로 인해 고성능 및 시스템 프로그래밍에 적합합니다.

Python 또는 C를 선택하는 것은 프로젝트 요구 사항에 따라 다릅니다. 1) 빠른 개발, 데이터 처리 및 프로토 타입 설계가 필요한 경우 Python을 선택하십시오. 2) 고성능, 낮은 대기 시간 및 근접 하드웨어 제어가 필요한 경우 C를 선택하십시오.

매일 2 시간의 파이썬 학습을 투자하면 프로그래밍 기술을 효과적으로 향상시킬 수 있습니다. 1. 새로운 지식 배우기 : 문서를 읽거나 자습서를 시청하십시오. 2. 연습 : 코드를 작성하고 완전한 연습을합니다. 3. 검토 : 배운 내용을 통합하십시오. 4. 프로젝트 실무 : 실제 프로젝트에서 배운 것을 적용하십시오. 이러한 구조화 된 학습 계획은 파이썬을 체계적으로 마스터하고 경력 목표를 달성하는 데 도움이 될 수 있습니다.

2 시간 이내에 Python을 효율적으로 학습하는 방법 : 1. 기본 지식을 검토하고 Python 설치 및 기본 구문에 익숙한 지 확인하십시오. 2. 변수, 목록, 기능 등과 같은 파이썬의 핵심 개념을 이해합니다. 3. 예제를 사용하여 마스터 기본 및 고급 사용; 4. 일반적인 오류 및 디버깅 기술을 배우십시오. 5. 목록 이해력 사용 및 PEP8 스타일 안내서와 같은 성능 최적화 및 모범 사례를 적용합니다.

Python은 초보자 및 데이터 과학에 적합하며 C는 시스템 프로그래밍 및 게임 개발에 적합합니다. 1. 파이썬은 간단하고 사용하기 쉽고 데이터 과학 및 웹 개발에 적합합니다. 2.C는 게임 개발 및 시스템 프로그래밍에 적합한 고성능 및 제어를 제공합니다. 선택은 프로젝트 요구와 개인적인 이익을 기반으로해야합니다.

Python은 데이터 과학 및 빠른 개발에 더 적합한 반면 C는 고성능 및 시스템 프로그래밍에 더 적합합니다. 1. Python Syntax는 간결하고 학습하기 쉽고 데이터 처리 및 과학 컴퓨팅에 적합합니다. 2.C는 복잡한 구문을 가지고 있지만 성능이 뛰어나고 게임 개발 및 시스템 프로그래밍에 종종 사용됩니다.

파이썬을 배우기 위해 하루에 2 시간을 투자하는 것이 가능합니다. 1. 새로운 지식 배우기 : 목록 및 사전과 같은 1 시간 안에 새로운 개념을 배우십시오. 2. 연습 및 연습 : 1 시간을 사용하여 소규모 프로그램 작성과 같은 프로그래밍 연습을 수행하십시오. 합리적인 계획과 인내를 통해 짧은 시간에 Python의 핵심 개념을 마스터 할 수 있습니다.

Python은 배우고 사용하기 쉽고 C는 더 강력하지만 복잡합니다. 1. Python Syntax는 간결하며 초보자에게 적합합니다. 동적 타이핑 및 자동 메모리 관리를 사용하면 사용하기 쉽지만 런타임 오류가 발생할 수 있습니다. 2.C는 고성능 응용 프로그램에 적합한 저수준 제어 및 고급 기능을 제공하지만 학습 임계 값이 높고 수동 메모리 및 유형 안전 관리가 필요합니다.


핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

Video Face Swap
완전히 무료인 AI 얼굴 교환 도구를 사용하여 모든 비디오의 얼굴을 쉽게 바꾸세요!

인기 기사

뜨거운 도구

SecList
SecLists는 최고의 보안 테스터의 동반자입니다. 보안 평가 시 자주 사용되는 다양한 유형의 목록을 한 곳에 모아 놓은 것입니다. SecLists는 보안 테스터에게 필요할 수 있는 모든 목록을 편리하게 제공하여 보안 테스트를 더욱 효율적이고 생산적으로 만드는 데 도움이 됩니다. 목록 유형에는 사용자 이름, 비밀번호, URL, 퍼징 페이로드, 민감한 데이터 패턴, 웹 셸 등이 포함됩니다. 테스터는 이 저장소를 새로운 테스트 시스템으로 간단히 가져올 수 있으며 필요한 모든 유형의 목록에 액세스할 수 있습니다.

SublimeText3 Linux 새 버전
SublimeText3 Linux 최신 버전

MinGW - Windows용 미니멀리스트 GNU
이 프로젝트는 osdn.net/projects/mingw로 마이그레이션되는 중입니다. 계속해서 그곳에서 우리를 팔로우할 수 있습니다. MinGW: GCC(GNU Compiler Collection)의 기본 Windows 포트로, 기본 Windows 애플리케이션을 구축하기 위한 무료 배포 가능 가져오기 라이브러리 및 헤더 파일로 C99 기능을 지원하는 MSVC 런타임에 대한 확장이 포함되어 있습니다. 모든 MinGW 소프트웨어는 64비트 Windows 플랫폼에서 실행될 수 있습니다.

Atom Editor Mac 버전 다운로드
가장 인기 있는 오픈 소스 편집기

DVWA
DVWA(Damn Vulnerable Web App)는 매우 취약한 PHP/MySQL 웹 애플리케이션입니다. 주요 목표는 보안 전문가가 법적 환경에서 자신의 기술과 도구를 테스트하고, 웹 개발자가 웹 응용 프로그램 보안 프로세스를 더 잘 이해할 수 있도록 돕고, 교사/학생이 교실 환경 웹 응용 프로그램에서 가르치고 배울 수 있도록 돕는 것입니다. 보안. DVWA의 목표는 다양한 난이도의 간단하고 간단한 인터페이스를 통해 가장 일반적인 웹 취약점 중 일부를 연습하는 것입니다. 이 소프트웨어는
