数据结构与算法-优先级队列

定义

1)满二叉树:一个高为 h h h的二叉树,如果其节点个数等于 2 h − 1 2^h-1 2h1,则是一个满二叉数。
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;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值