-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
alezai
committed
Apr 22, 2016
1 parent
927aaea
commit 5d35211
Showing
9 changed files
with
263 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
//: Playground - noun: a place where people can play | ||
var heap = BinaryHeap<Int>.init(array: [7, 1, 5, 2, 9]) | ||
|
||
heap.minimum() | ||
|
||
heap.deleteMin() | ||
heap.deleteMin() | ||
heap.deleteMin() | ||
|
||
heap.minimum() | ||
|
||
heap.insert(4) | ||
heap.insert(3) | ||
|
||
heap.debugDescription | ||
heap.removeAtIndex(1) | ||
heap.debugDescription | ||
|
||
heap.removeAll() |
119 changes: 119 additions & 0 deletions
119
BinaryHeap/BinaryHeap.playground/Sources/BinaryHeap.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
/* | ||
BinaryHeap - Min | ||
*/ | ||
|
||
public struct BinaryHeap<T: Comparable> { | ||
private var elements = [T]() | ||
|
||
public init(array: [T]) { | ||
buildHeap(array) | ||
} | ||
|
||
private mutating func percolateUpAtIndex(index: Int) { | ||
assert(index < elements.count) | ||
let element = elements[index] | ||
var i = index | ||
var child = i | ||
while i != 0 && elements[(i - 1) / 2] > element { | ||
elements[i] = elements[(i - 1) / 2] | ||
child = i | ||
i = (i - 1) / 2 | ||
} | ||
if i == 0 { | ||
if elements[0] > element { | ||
elements[child] = elements[0] | ||
}else { | ||
i = child | ||
} | ||
} | ||
elements[i] = element | ||
} | ||
|
||
private mutating func percolateDownAtIndex(index: Int, lastElementIndex: Int) { | ||
assert(index < elements.count) | ||
let element = elements[index] | ||
let lastElement = elements[lastElementIndex] | ||
var i = index | ||
|
||
while i * 2 + 1 < elements.count { | ||
var child = 2 * i + 1 | ||
if child != elements.count - 1 && elements[child + 1] < elements[child] { | ||
child += 1 | ||
} | ||
if elements[child] < lastElement{ | ||
elements[i] = elements[child] | ||
}else { | ||
break | ||
} | ||
i = child | ||
} | ||
elements[i] = lastElement | ||
elements[lastElementIndex] = element | ||
} | ||
} | ||
|
||
//MARK: - Basic Operations | ||
extension BinaryHeap { | ||
private mutating func buildHeap(array: [T]) { | ||
for element in array { | ||
insert(element) | ||
} | ||
} | ||
|
||
public mutating func insert(element: T) { | ||
elements.append(element) | ||
percolateUpAtIndex(elements.count - 1) | ||
} | ||
|
||
public mutating func deleteMin() { | ||
assert(elements.count > 0) | ||
percolateDownAtIndex(0, lastElementIndex: elements.count - 1) | ||
elements.removeLast() | ||
} | ||
|
||
public func minimum() -> T? { | ||
return elements.first | ||
} | ||
|
||
public mutating func removeAtIndex(index: Int) { | ||
assert(index < elements.count) | ||
elements[index] = minimum()! | ||
percolateUpAtIndex(index) | ||
deleteMin() | ||
} | ||
|
||
public mutating func removeAll() { | ||
elements.removeAll() | ||
} | ||
} | ||
|
||
//MARK: - Debug | ||
extension BinaryHeap: CustomStringConvertible { | ||
public var description: String { | ||
if elements.count > 0 { | ||
return descriptionAtIndex(0) | ||
}else { | ||
return "nil" | ||
} | ||
} | ||
|
||
private func descriptionAtIndex(index: Int) -> String { | ||
var s = "" | ||
let left = 2 * index + 1 | ||
if left < elements.count { | ||
s += "(\(descriptionAtIndex(left)))<- " | ||
} | ||
s += "\(elements[index])" | ||
let right = left + 1 | ||
if right < elements.count { | ||
s += " ->(\(descriptionAtIndex(right)))" | ||
} | ||
return s | ||
} | ||
} | ||
|
||
extension BinaryHeap: CustomDebugStringConvertible { | ||
public var debugDescription: String { | ||
return elements.description | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> | ||
<playground version='5.0' target-platform='osx'> | ||
<timeline fileName='timeline.xctimeline'/> | ||
</playground> |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
# 堆 | ||
|
||
## 二叉堆 | ||
|
||
### 结构性质 | ||
|
||
二叉堆是一颗完全二叉树 | ||
|
||
![CompleteBinaryTree](Image/CompleteBinaryTree.png) | ||
|
||
容易得出结论: | ||
|
||
* 一颗高为h的完全二叉树,有2^h到2^(h+1) - 1个节点 | ||
* 对于位置i,左儿子在2i,右儿子在2i+1,父亲在i/2 | ||
|
||
### 堆序性质 | ||
|
||
任意节点值小于它的所有后裔 | ||
|
||
![BinaryHeap](Image/BinaryHeap.png) | ||
|
||
### 堆操作的两个关键方法 | ||
|
||
#### 上滤 | ||
|
||
![percolateUp](Image/percolateUp.png) | ||
|
||
```swift | ||
private mutating func percolateUpAtIndex(index: Int) { | ||
assert(index < elements.count) | ||
let element = elements[index] | ||
var i = index | ||
var child = i | ||
while i != 0 && elements[(i - 1) / 2] > element { | ||
elements[i] = elements[(i - 1) / 2] | ||
child = i | ||
i = (i - 1) / 2 | ||
} | ||
if i == 0 { | ||
if elements[0] > element { | ||
elements[child] = elements[0] | ||
}else { | ||
i = child | ||
} | ||
} | ||
elements[i] = element | ||
} | ||
``` | ||
|
||
|
||
|
||
#### 下滤 ![percolateDown](Image/percolateDown.png) | ||
|
||
```swift | ||
private mutating func percolateDownAtIndex(index: Int, lastElementIndex: Int) { | ||
assert(index < elements.count) | ||
let element = elements[index] | ||
let lastElement = elements[lastElementIndex] | ||
var i = index | ||
|
||
while i * 2 + 1 < elements.count { | ||
var child = 2 * i + 1 | ||
if child != elements.count - 1 && elements[child + 1] < elements[child] { | ||
child += 1 | ||
} | ||
if elements[child] < lastElement{ | ||
elements[i] = elements[child] | ||
}else { | ||
break | ||
} | ||
i = child | ||
} | ||
elements[i] = lastElement | ||
elements[lastElementIndex] = element | ||
} | ||
``` | ||
|
||
|
||
|
||
### 基本操作 | ||
|
||
#### 插入 | ||
|
||
在数组末尾插入,然后对其进行上滤操作 | ||
|
||
```swift | ||
public mutating func insert(element: T) { | ||
elements.append(element) | ||
percolateUpAtIndex(elements.count - 1) | ||
} | ||
``` | ||
|
||
#### 建堆 | ||
|
||
依序执行插入即可 | ||
|
||
```swift | ||
private mutating func buildHeap(array: [T]) { | ||
for element in array { | ||
insert(element) | ||
} | ||
} | ||
``` | ||
|
||
#### 删除最小元 | ||
|
||
将数组第一个元素替换为数组的最后一个元素,对第一个元素进行下滤操作,最后删除数组最后一个元素即可 | ||
|
||
```swift | ||
public mutating func deleteMin() { | ||
assert(elements.count > 0) | ||
percolateDownAtIndex(0, lastElementIndex: elements.count - 1) | ||
elements.removeLast() | ||
} | ||
``` | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -21,3 +21,8 @@ | |
## 散列表 | ||
|
||
- [HashTable](HashTable/) key-value-coding | ||
|
||
## 堆 | ||
|
||
* [BinaryHeap](BinaryHeap/) | ||
|