定义
1)满二叉树:一个高为
h
h
h的二叉树,如果其节点个数等于
2
h
−
1
2^h-1
2h−1,则是一个满二叉数。
2)完全二叉树:将满二叉数从根节点开始按层从上到下从左到右编号,如果将满二叉树编号最大的若干个(可以是0个)节点删除的话,形成的新树就是一个完全二叉树
3)大(小)根树:是这样的一颗树,树中每个节点的值都大于(小于)或等于其子节点(如果有子节点的化)的值。注意这里并没有要求是二叉树,可以多任意叉数)
4)大(小)根
堆
堆
堆:既是大(小)根树,又是完全二叉树。注意这里必须是完全的且是二叉的树。
完全二叉树需要记住的基本知识点:
1)编号为n的节点的父节点的编号为 n/2; 例如3号节点的父节点为 3/2 = 1号节点
2)编号为n的节点左孩子节点编号为 2n,右孩子节点为2n+1。当前前提是n号节点有左右孩子。当2n 等于二叉树所有节点总数时,n号节点有左孩子,当2n 小于 二叉树所有节点总数时,n号节点有右孩子。
大根堆实现代码:max_heap.h
#include <vector>
#include <iostream>
template <typename T>
class MaxHeapT
{
public:
MaxHeapT(const std::vector<T> &_data);
T top();
void pop();
void push(const T &data);
size_t size();
template <typename T1>
friend std::ostream &operator<<(std::ostream &out, MaxHeapT<T1> &_max_heap);
private:
void initialize(const std::vector<T> &_data);
std::vector<T> elements_;
size_t element_num_ = 0;
};
template <typename T>
MaxHeapT<T>::MaxHeapT(const std::vector<T> &_data) : element_num_(_data.size())
{
initialize(_data);
}
template <typename T>
void MaxHeapT<T>::initialize(const std::vector<T> &_data)
{
T a;
elements_.push_back(a);
elements_.insert(elements_.end(), _data.begin(), _data.end());
size_t root_node_index = element_num_ / 2;
for (; root_node_index > 0; root_node_index--)
{
size_t current_node_index = root_node_index;
T current_node_value = elements_[current_node_index];
size_t left_child_index = current_node_index * 2; //left_child_index
while (left_child_index <= element_num_)
{
T larger_child_value = elements_.at(left_child_index); //left_child_value
size_t larger_child_index = left_child_index;
if (left_child_index < element_num_)
{
size_t right_child_index = left_child_index + 1;
larger_child_index = elements_[left_child_index] >= elements_[right_child_index] ? left_child_index : right_child_index;
larger_child_value = elements_[larger_child_index];
}
if (current_node_value >= larger_child_value)
{
break;
}
std::swap(elements_[current_node_index], elements_[larger_child_index]);
current_node_index = larger_child_index;
left_child_index = current_node_index * 2;
}
}
}
template <typename T>
T MaxHeapT<T>::top()
{
//assert(element_num_ >= 1);
return elements_[1];
}
template <typename T>
void MaxHeapT<T>::pop()
{
if (element_num_ == 0)
return;
if (element_num_ == 1)
{
elements_.pop_back();
element_num_--;
return;
}
elements_[1] = elements_[element_num_];
element_num_--;
elements_.pop_back();
size_t current_node_index = 1;
size_t left_child_index = current_node_index * 2;
while (left_child_index <= element_num_)
{
T current_node_value = elements_[current_node_index];
size_t larger_child_index = left_child_index;
T larger_child_value = elements_[larger_child_value];
if (left_child_index < element_num_)
{
size_t right_child_index = left_child_index + 1;
larger_child_index = elements_[left_child_index] >= elements_[right_child_index] ? left_child_index : right_child_index;
larger_child_value = elements_[larger_child_index];
}
if (current_node_value >= larger_child_value)
{
break;
}
std::swap(elements_[current_node_index], elements_[larger_child_index]);
current_node_index = larger_child_index;
left_child_index = current_node_index * 2;
}
}
template <typename T>
void MaxHeapT<T>::push(const T &data)
{
elements_.push_back(data);
element_num_++;
size_t current_nodex_index = element_num_;
size_t parent_node_index = current_nodex_index / 2;
while (parent_node_index > 0)
{
if (elements_[current_nodex_index] > elements_[parent_node_index])
{
std::swap(elements_[current_nodex_index], elements_[parent_node_index]);
current_nodex_index = parent_node_index;
parent_node_index = current_nodex_index / 2;
}
else
{
break;
}
}
}
template <typename T>
size_t MaxHeapT<T>::size()
{
return element_num_;
}
template <typename T>
std::ostream &operator<<(std::ostream &out, MaxHeapT<T> &_max_heap)
{
if (_max_heap.element_num_ < 1)
{
out << " no element in maxHeap" << std::endl;
}
else
{
for (size_t i = 1; i <= _max_heap.element_num_; i++)
{
out << _max_heap.elements_[i] << " ";
}
out << std::endl;
}
return out;
}
测试代码: main.cpp
#include <iostream>
#include <vector>
#include "max_heap.h"
int main()
{
std::vector<double> datas_double = {3.0,4.0,5.0};
MaxHeapT<double> max_heap_t(datas_double);
max_heap_t.push(8.0);
std::cout<<max_heap_t;
max_heap_t.push(7);
std::cout<<max_heap_t;
max_heap_t.pop();
std::cout<<max_heap_t;
return 0;
}
编译指令:
g++ --std=c++11 main.cpp
运行结果:
8 5 3 4
8 7 3 4 5
7 5 3 4
利用小根堆进行排序列表合并:
Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity.
Example:
Input:
[
1->4->5,
1->3->4,
2->6
]
Output: 1->1->2->3->4->4->5->6
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/merge-k-sorted-lists
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
题解:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class MinHeap{
public:
MinHeap(vector<ListNode*> &lists);
ListNode* top();
void pop();
void push(ListNode* _node);
size_t size();
private:
void initilize(std::vector<ListNode*> &lists);
std::vector<ListNode*> node_elements_;
size_t element_num_;
};
MinHeap::MinHeap(vector<ListNode*> &lists)
{
initilize(lists);
}
void MinHeap::initilize(std::vector<ListNode*> &lists)
{
node_elements_.emplace_back(static_cast<ListNode*>(nullptr));
for(auto &node_ptr : lists)
{
if(node_ptr != nullptr)
{
node_elements_.emplace_back(node_ptr);
}
}
element_num_ = node_elements_.size() - 1;
size_t root_index = element_num_ / 2;
for(; root_index > 0; root_index--)
{
size_t current_node_index = root_index;
ListNode* current_node_value = node_elements_[current_node_index];
size_t left_child_index = current_node_index * 2;
while(left_child_index <= element_num_)
{
size_t smaller_node_index = left_child_index;
ListNode* smaller_node_value = node_elements_[left_child_index];
if(left_child_index < element_num_)
{
size_t right_child_index = left_child_index + 1;
smaller_node_index = node_elements_[left_child_index]->val <= node_elements_[right_child_index]->val ?
left_child_index : right_child_index;
smaller_node_value = node_elements_[smaller_node_index];
}
if(current_node_value->val <= smaller_node_value->val)
{
break;
}
std::swap(node_elements_[current_node_index],node_elements_[smaller_node_index]);
current_node_index = smaller_node_index;
left_child_index = current_node_index * 2;
}
}
}
ListNode* MinHeap::top()
{
if(element_num_ < 1)
return nullptr;
return node_elements_[1];
}
void MinHeap::pop()
{
if(element_num_ < 1)
return;
if(element_num_ == 1)
{
node_elements_.pop_back();
element_num_--;
return;
}
node_elements_[1] = node_elements_[element_num_];
node_elements_.pop_back();
element_num_--;
size_t current_node_index = 1;
size_t left_child_index = current_node_index * 2;
while(left_child_index <= element_num_)
{
size_t smaller_node_index = left_child_index;
ListNode* smaller_node_value = node_elements_[left_child_index];
if(left_child_index < element_num_)
{
size_t right_child_index = left_child_index + 1;
smaller_node_index = node_elements_[left_child_index]->val <= node_elements_[right_child_index]->val ?
left_child_index : right_child_index;
}
if(node_elements_[current_node_index]->val > node_elements_[smaller_node_index]->val)
{
std::swap(node_elements_[current_node_index],node_elements_[smaller_node_index]);
}
else
{
break;
}
current_node_index = smaller_node_index;
left_child_index = current_node_index * 2;
}
}
void MinHeap::push(ListNode* _node)
{
if(_node == nullptr)
return;
if(element_num_ == 0)
{
node_elements_.emplace_back(_node);
element_num_++;
return;
}
node_elements_.emplace_back(_node);
element_num_++;
size_t current_node_index = element_num_;
size_t parent_node_index = current_node_index / 2;
while(parent_node_index > 0)
{
if(node_elements_[current_node_index]->val < node_elements_[parent_node_index]->val)
{
std::swap(node_elements_[current_node_index],node_elements_[parent_node_index]);
current_node_index = parent_node_index;
parent_node_index = current_node_index / 2;
}
else
{
break;
}
}
}
size_t MinHeap::size()
{
return element_num_;
}
class Solution {
public:
ListNode* mergeKLists(vector<ListNode*>& lists) {
MinHeap min_heap(lists);
ListNode* head_node = min_heap.top();
ListNode* current_node = head_node;
while(min_heap.size() > 0)
{
min_heap.pop();
if(current_node != nullptr)
min_heap.push(current_node->next);
current_node->next = min_heap.top();
current_node = current_node->next;
}
return head_node;
}
};
除了用最大堆可以解上面的题,使用最大左高树也可以解
struct BinaryNode
{
std::pair<size_t,ListNode*> element;
BinaryNode *left;
BinaryNode *right;
BinaryNode(std::pair<size_t,ListNode*> &_element, BinaryNode *_left = nullptr, BinaryNode *_right = nullptr) : element(_element), left(_left), right(_right)
{
}
};
class MinHBLT
{
public:
MinHBLT(vector<ListNode*> &lists);
MinHBLT();
void pop();
void push(ListNode *_element);
ListNode* top();
size_t size();
void print_level();
void print_mid();
void print_back();
private:
/*注意:这里的参数需要是指针的引用类型*/
void merge(BinaryNode *&x, BinaryNode *&y);
void initialize(vector<ListNode*> &lists);
void print_mid(BinaryNode *_node);
void print_back(BinaryNode *_node);
private:
BinaryNode *root_;
size_t element_num_;
};
void MinHBLT::merge(BinaryNode *&x, BinaryNode *&y)
{
if (y == nullptr)
{
return;
}
if (x == nullptr)
{
x = y;
return;
}
if (x->element.second->val > y->element.second->val)
{
std::swap(x, y);
}
if (x->left == nullptr)
{
x->left = y;
x->right = nullptr;
x->element.first = 1;
}
else
{
merge(x->right,y);
if (x->left->element.first < x->right->element.first)
std::swap(x->left, x->right);
x->element.first = x->right->element.first + 1;
}
}
void MinHBLT::pop()
{
if(root_ != nullptr)
{
BinaryNode *x = root_->left;
BinaryNode *y = root_->right;
delete root_;
merge(x, y);
root_ = x;
element_num_--;
}
}
void MinHBLT::push(ListNode* _element)
{
if(_element != nullptr)
{
std::pair<size_t,ListNode*> ele = std::make_pair(1, _element);
BinaryNode *y = new BinaryNode(ele);
merge(root_, y);
element_num_++;
}
}
ListNode* MinHBLT::top()
{
if(element_num_ < 1)
return nullptr;
return root_->element.second;
}
void MinHBLT::initialize(vector<ListNode*> &lists)
{
std::queue<BinaryNode *> tree_queue;
for (size_t i = 0; i < lists.size(); i++)
{
if(lists[i] != nullptr)
{
std::pair<size_t, ListNode*> element = std::make_pair(1, lists[i]);
tree_queue.push(new BinaryNode(element));
}
}
element_num_ = tree_queue.size();
for (size_t i = 1; i < element_num_; i++)
{
BinaryNode *x = tree_queue.front();
tree_queue.pop();
BinaryNode *y = tree_queue.front();
tree_queue.pop();
merge(x, y);
tree_queue.push(x);
}
root_ = tree_queue.front();
}
MinHBLT::MinHBLT(vector<ListNode*> &lists)
{
initialize(lists);
}
MinHBLT::MinHBLT()
{
root_ = nullptr;
element_num_ = 0;
}
size_t MinHBLT::size()
{
return element_num_;
}
class Solution {
public:
ListNode* mergeKLists(vector<ListNode*>& lists) {
//MinHeap min_heap(lists);
MinHBLT min_hblt(lists);
//ListNode* head_node = min_heap.top();
ListNode* head_node = min_hblt.top();
ListNode* current_node = head_node;
//while(min_heap.size() > 0)
while(min_hblt.size() > 0)
{
//min_heap.pop();
min_hblt.pop();
if(current_node != nullptr)
//min_heap.push(current_node->next);
min_hblt.push(current_node->next);
//current_node->next = min_heap.top();
current_node->next = min_hblt.top();
current_node = current_node->next;
}
return head_node;
}
};