Merge pull request #370 from caitlingao/28_heap

feat(geektime_algo): add 28 heap
This commit is contained in:
wangzheng0822 2019-08-05 08:56:39 +08:00 committed by GitHub
commit 06c7d17007
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 190 additions and 0 deletions

View File

@ -0,0 +1,53 @@
// 建堆,自底向上堆化
pub fn build_heap_down_up(nums: &mut Vec<i32>) {
for i in 1..nums.len() {
heapify_down_up(nums, i);
}
}
fn heapify_down_up(nums: &mut Vec<i32>, idx: usize) {
let mut idx = idx;
let mut parent_idx = idx - 1 >> 1;
while nums[idx] > nums[parent_idx] {
swap(nums, idx, parent_idx);
idx = parent_idx;
if idx == 0 { break; }
parent_idx = idx - 1 >> 1;
}
}
// 建堆,自上向下堆化
pub fn build_heap_up_down(nums: &mut Vec<i32>) {
let nums_len = nums.len();
for i in (0..nums_len).rev() {
heapify_up_down(nums, i, nums_len);
}
}
fn heapify_up_down(nums: &mut Vec<i32>, idx: usize, nums_len: usize) {
let mut idx = idx;
loop {
let mut max_pos = idx;
if 2 * idx + 1 < nums_len && nums[idx] < nums[2 * idx + 1] { max_pos = 2 * idx + 1; }
if 2 * idx + 2 < nums_len && nums[max_pos] < nums[2 * idx + 2] { max_pos = 2 * idx + 2; }
if max_pos == idx { break; }
swap(nums, idx, max_pos);
idx = max_pos;
}
}
fn swap(nums: &mut Vec<i32>, idx: usize, parent_idx: usize) {
let tmp = nums[parent_idx];
nums[parent_idx] = nums[idx];
nums[idx] = tmp;
}
fn main() {
let mut nums = vec![1, 4, 5, 7, 8, 13, 16, 19, 20];
build_heap_down_up(&mut nums);
println!("{:?}", nums);
let mut nums1 = vec![1, 4, 5, 7, 8, 13, 16, 19, 20];
build_heap_up_down(&mut nums1);
println!("{:?}", nums1);
}

98
rust/28_heap/heap.rs Normal file
View File

@ -0,0 +1,98 @@
#[derive(Debug)]
struct Heap {
data: Vec<Option<i32>>,
capacity: usize,
count: i32,
}
impl Heap {
pub fn new(capacity: usize) -> Self {
Heap {
data: vec![None; capacity],
capacity: capacity,
count: 0
}
}
pub fn insert(&mut self, x: i32) -> bool {
// 堆已满
if self.capacity as i32 == self.count { return false; }
self.data[self.count as usize] = Some(x);
if self.count == 0 {
self.count += 1;
return true;
}
let mut idx = self.count as usize;
// 子节点大于父节点,子节点与父节点交换
// 自底向上堆化
let mut parent_idx = ((idx - 1) >> 1) as usize;
while parent_idx > 0 && self.data[idx] > self.data[parent_idx] {
self.swap(idx, parent_idx);
idx = parent_idx;
parent_idx = ((idx - 1) >> 1) as usize;
}
self.count += 1;
true
}
pub fn remove_max(&mut self) -> Option<i32> {
// 堆已空
if self.count == 0 { return None; }
let max_value = self.data[0];
// 将最后一个叶子节点移至堆顶
self.data[0] = self.data[(self.count - 1) as usize];
self.data[(self.count - 1) as usize] = None;
self.heapify();
self.count -= 1;
max_value
}
// 堆化,自上向下堆化
fn heapify(&mut self) {
let mut idx = 0usize;
loop {
let mut max_pos = idx;
if (2 * idx + 1) as i32 <= self.count && self.data[idx] < self.data[2 * idx + 1] { max_pos = 2 * idx + 1; }
if (2 * idx + 2) as i32 <= self.count && self.data[max_pos] < self.data[2 * idx + 2] { max_pos = 2 * idx + 2; }
if max_pos == idx { break; }
self.swap(idx, max_pos);
idx = max_pos;
}
}
fn swap(&mut self, idx: usize, parent_idx: usize) {
let tmp = self.data[parent_idx];
self.data[parent_idx] = self.data[idx];
self.data[idx] = tmp;
}
}
fn main() {
let mut h = Heap::new(16);
h.insert(33);
h.insert(27);
h.insert(21);
h.insert(16);
h.insert(13);
h.insert(15);
h.insert(9);
h.insert(5);
h.insert(6);
h.insert(7);
h.insert(8);
h.insert(1);
h.insert(2);
h.insert(22);
println!("{:?}", h);
h.remove_max();
println!("{:?}", h);
h.remove_max();
println!("{:?}", h);
h.remove_max();
println!("{:?}", h);
}

39
rust/28_heap/sort_heap.rs Normal file
View File

@ -0,0 +1,39 @@
pub fn sort(nums: &mut Vec<i32>) {
build_heap(nums);
for i in (0..nums.len()).rev() {
swap(nums, 0, i);
heapify(nums, 0, i);
}
}
fn build_heap(nums: &mut Vec<i32>) {
let nums_len = nums.len();
for i in (0..nums_len).rev() {
heapify(nums, i, nums_len);
}
}
fn heapify(nums: &mut Vec<i32>, idx: usize, nums_len: usize) {
let mut idx = idx;
loop {
let mut max_pos = idx;
if 2 * idx + 1 < nums_len && nums[idx] < nums[2 * idx + 1] { max_pos = 2 * idx + 1; }
if 2 * idx + 2 < nums_len && nums[max_pos] < nums[2 * idx + 2] { max_pos = 2 * idx + 2; }
if max_pos == idx { break; }
swap(nums, idx, max_pos);
idx = max_pos;
}
}
fn swap(nums: &mut Vec<i32>, idx: usize, parent_idx: usize) {
let tmp = nums[parent_idx];
nums[parent_idx] = nums[idx];
nums[idx] = tmp;
}
fn main() {
let mut nums = vec![9, 6, 3, 1, 5];
sort(&mut nums);
println!("{:?}", nums);
}