【数据结构】堆结构小根堆,大根堆,插入,删除等操作的实现

https://blog.csdn.net/sofia_m/article/details/79117088

实现代码:

#include<iostream>
#include<vector>
#include<iostream>
#include<stdio.h>

using namespace std;

using namespace std;

template<class T>
class Less
{
public:
    bool operator()(T& left, T& right){
        return left < right;
    }
};

template<class T>
class Greater
{
public:
    bool operator()(T& left, T& right){
        return left>right;
    }
};

template<class T,class Compare = Greater<T>>
class Heap
{
public:
    //无参构造
    Heap()
    {}
    //带参构造
    Heap(T* arr, const T size){
        _v.reserve(size);
        for (int i = 0; i < size; ++i){
            _v.push_back(arr[i]);
        }
        //建堆
        for (int j = (_v.size() - 2) >> 1; j >= 0; --j){
            //向下调整
            _AdjustDown(j);
        }
    }

    void Push(const T& data){
        _v.push_back(data);
        _AdjustUp(_v.size() - 1);
    }

    void Pop(){
        //交换堆顶元素与堆底元素
        size_t size = _v.size();
        swap(_v[0], _v[size - 1]);
        //删除堆底元素
        _v.pop_back();
        //向下调整
        _AdjustDown(0);
    }

    size_t Size(){
        return _v.size();
    }

    bool Empty(){
        return _v.empty();
    }

    //打印堆
    void Print(){
        for (size_t i = 0; i < _v.size(); ++i){
            cout << _v[i] << "  ";
        }
        cout << endl;
    }

    T Top()const
    {
        return _v.front();
    }

    T Back()const
    {
        return _v.back();
    }

    //析构
    ~Heap(){
        _v.~vector();
    }

protected:
    //向下调整
    void _AdjustDown(size_t root){
        size_t parent = root;
        size_t min_child = parent * 2 + 1;
        while (min_child < _v.size()){
            if ((min_child + 1 < _v.size()) && (Compare()(_v[min_child + 1],_v[min_child])))
                min_child += 1;
            if (Compare()(_v[min_child],_v[parent])){
                swap(_v[parent], _v[min_child]);
                parent = min_child;
                min_child = parent * 2 + 1;
            }
            else{
                break;
            }
        }
    }

    //向上调整
    void _AdjustUp(size_t index){
        size_t child = index;
        size_t parent = (child - 1) >> 1;
        while (child){
            /*if (Compare()(_v[parent],_v[child])){
                break;
            }
            else{
                swap(_v[parent], _v[child]);
                child = parent;
                parent = (child - 1) >> 1;
            }*/
			
			if (Compare()(_v[parent],_v[child]))
			{
				swap(_v[parent], _v[child]);
                child = parent;
                parent = (child - 1) >> 1;
            }
            else
			{
                break;
            }
        }
    }

private:
    vector<T> _v;
};

 
//test.cpp




class Solution {
//priority_queue<int, vector<int>, less<int> > p;	//大根堆
//priority_queue<int, vector<int>, greater<int> > q;	//小根堆

public:

	
	void Insert(int num)
	{
		if(count % 2 == 0)
		{
			//偶数个元素时,加入到小根堆,但要经过大根堆排序,大根堆堆顶弹出给小根堆
			PushMaxHeapElem(num);
			int v = MaxHeapFront();
			PopMaxHeapElem();
			
			PushMinHeapElem(v);
		}
		else
		{
			//奇数个元素时,加入到大根堆,但要经过小根堆排序,小根堆堆顶弹出给大根堆
			PushMinHeapElem(num);
			int v = MinHeapFront();
			PopMinHeapElem();
			
			PushMaxHeapElem(v);
		}
		
		count++;
	}
	
	double GetMedian()
	{ 
		if(count % 2 == 0)
		{
			
			double s = MinHeapFront() + MaxHeapFront();
			return (double)((s) / 2);
		}
		else
		{
			return (double)MinHeapFront();
		}
	}
	
	
	int MinHeapFront()
	{
		return vecMin.front();
	}
	//最小堆元素下沉
	void MinHeapElemDown(vector<int> &vec, int len, int index)
	{
		if(index < 0 || index >= len)
		{
			return;
		}
		
		int parent = index;
		int child = 2 * parent + 1;
		
		while(child < len)
		{
			//右子节点
			if(child + 1 < len && vecMin[child] > vecMin[child + 1])
			{
				child++;
			}
			
			if(vecMin[parent] > vecMin[child])
			{
				Swap(&vecMin[parent], &vecMin[child]);
			}
			
			parent = child;
			child = 2 * parent + 1;
		}
	}
	
	void BuildMinHeap()
	{
		int len = vecMin.size();
		
		for(int i = len / 2 - 1; i >= 0; i++)
		{
			MinHeapElemDown(vecMin, len, i);
		}
	}
	
	void PushMinHeapElem(int data)
	{
		vecMin.push_back(data);
		//添加元素后元素上升
		MinHeapElemUp(vecMin, vecMin.size(), vecMin.size() - 1);
	}
	
	void PopMinHeapElem()
	{
		//首位元素交换
		Swap(&vecMin[0], &vecMin[vecMin.size() - 1]);
		
		//堆底元素弹出
		vecMin.pop_back();
		
		//元素下沉
		MinHeapElemDown(vecMin, vecMin.size(), 0);
	}
	
	//在后边添加元素,从最后开始元素上升
	void MinHeapElemUp(vector<int> &vec, int len, int index)
	{
		int child = index;
		int parent = (child - 1) >> 1;
		while(child)
		{
			if(vecMin[child] < vecMin[parent])
			{
				Swap(&vecMin[child], &vecMin[parent]);
				
				child = parent;
				parent = (child - 1) >> 1;
			}
			else
			{
				break;
			}
		}
	}
	
	
	
	
	
	
	
	
	int MaxHeapFront()
	{
		return vecMax.front();
	}
	
	
	void MaxHeapElemDown(vector<int> &vec, int len, int index)
	{
		if(index < 0 || index >= len)
		{
			return;
		}
		
		int parent = index;
		int child = 2 * parent + 1;
		while(child < len - 1)
		{
			//左右子节点里大的
			if(child + 1 < len && vecMax[child] < vecMax[child + 1])
			{
				child++;
			}
			
			if(vecMax[parent] < vecMax[child])
			{
				Swap(&vec[parent], &vec[child]);
			}
			
			parent = child;
			child = 2 * parent + 1;
		}
	}
	
	//建最大堆
	void BuildMaxHeap()
	{
		int len = vecMax.size();
		
		for(int i = len / 2 - 1; i >= 0; i++)
		{
			MaxHeapElemDown(vecMax, len, i);
		}
	}
	
	void PushMaxHeapElem(int data)
	{
		vecMax.push_back(data);
		//添加元素后元素上升
		MaxHeapElemUp(vecMax, vecMax.size(), vecMax.size() - 1);
	}
	
	void PopMaxHeapElem()
	{
		//首位元素交换
		Swap(&vecMax[0], &vecMax[vecMax.size() - 1]);
		
		//堆底元素弹出
		vecMax.pop_back();
		
		//元素下沉
		MaxHeapElemDown(vecMax, vecMax.size(), 0);
	}
	
	//在后边添加元素,从最后开始元素上升
	void MaxHeapElemUp(vector<int> &vec, int len, int index)
	{
		int child = index;
		int parent = (child - 1) >> 1;
		while(child)
		{
			if(vecMax[child] > vecMax[parent])
			{
				Swap(&vecMax[child], &vecMax[parent]);
				child = parent;
				parent = (child - 1) >> 1;
			}
			else
			{
				break;
			}
		}
	}
	
	void Swap(int *v1, int *v2)
	{
		int temp = *v1;
		*v1 = *v2;
		*v2 = temp;
	}
	
	vector<int> vecMax;
	vector<int> vecMin;
	
	int count = 0;
};

void test(){
    int arr[] = { 53, 17, 78, 9, 45, 65, 87, 23 };
	//5,2,3,4,1,6,7,0,8
	
	
    Heap<int,Less<int> > hp;
    //此处传的是小堆Less<int>,若要大堆可传Greater<int>
    hp.Push(53);
	hp.Push(17);
	hp.Push(78);
	hp.Push(9);
	hp.Push(45);
	hp.Push(65);
	hp.Push(87);
	hp.Push(23);
    hp.Pop();
    cout << hp.Size() << endl;
    //cout << hp.Front() << endl;
    //cout << hp.Back() << endl;
	
	Solution sol;
	sol.Insert(5);
	sol.Insert(2);
	sol.Insert(3);
	sol.Insert(4);
	double mid = sol.GetMedian();
}

int main(){
    test();
    system("pause");
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

金士顿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值