最大最小堆排序

HeapSort.h
 
 
#ifndef _MAX_HEAPSORT_H_
#define _MAX_HEAPSORT_H_

template <typename T>
class CMaxHeap
{
	int m_capacity;
	int m_size;
	T*m_data;
public:
	CMaxHeap();
	CMaxHeap(const CMaxHeap& that);
	CMaxHeap& operator = (const CMaxHeap& that);
	~CMaxHeap();

	void Enter(const T& data);
	void Quit(T& data);
	void Clear();
	int Size();
};

#endif
 
 
HeapSort.cpp
#include "HeapSort.h"

template <typename T>
CMaxHeap<T>::CMaxHeap():m_capacity(8),m_size(0),m_data(new T[m_capacity])
{}

template <typename T>
CMaxHeap<T>::CMaxHeap(const CMaxHeap& that)
	:
	m_capacity(that.m_capacity),
	m_size(that.m_size)
{
	m_data = new T[m_capacity];
	for (int i = 0; i < m_size; ++i)
		m_data[i] = that.m_data[i];
}

template <typename T>
CMaxHeap<T>& CMaxHeap<T>::operator = (const CMaxHeap& that)
{
	if (*this != that)
	{
		delete m_data;
		m_capacity = that.m_capacity;
		m_size = that.m_size;
		m_data = new T[m_capacity];
		for (int i = 0; i < m_size; ++i)
			m_data[i] = that.m_data[i];
	}
}

template <typename T>
CMaxHeap<T>::~CMaxHeap()
{
	delete[] m_data;
}

template <typename T>
void CMaxHeap<T>::Enter(const T& data)
{
	//下表从1开始
	//先放入数据
	m_size += 1;
	m_data[m_size] = data;

	//调整下标
	//得到子节点下表以及父节点下标
	int child_index = m_size;//子节点下标
	int parent_index = child_index / 2;//父节点下标

	while (child_index > 1 &&
		m_data[child_index] > m_data[parent_index])
	{
		//数据交换
		T t = m_data[parent_index];
		m_data[parent_index] = m_data[child_index];
		m_data[child_index] = t;

		//更新下标
		child_index = parent_index;
		parent_index = child_index / 2;
	}

	//扩容
	if (m_size + 1 == m_capacity)
	{
		m_capacity *= 2;
		T* p = new T[m_capacity];
		for (int i = 1; i <= m_size; ++i)
			p[i] = m_data[i];
		delete[] m_data;
		m_data = p;
	}
}

template<typename T>
void CMaxHeap<T>::Quit(T & data)
{
	//没有数据的时候
	if (m_size == 0)
		return false;
	//只有一个数据的时候
	else if (m_size == 1)
	{
		data = m_data[1];
		m_size -= 1;
		return true;
	}

	//得到根节点数据
	data = m_data[1];
	//得到当前最大堆的下标
	int cur_index = 1;
	while (true)
	{
		//有3种可能需要调整情况
		//1)如果有左右子树
		//2)有左无右
		//3)无子树

		//得到左右子树的下标
		int left_index = cur_index * 2;
		int right_index = cur_index * 2 + 1;

		//有左有右子树
		if (right_index <= m_size)
		{
			if (m_data[left_index] < m_data[right_index])
			{
				m_data[cur_index] = m_data[right_index];
				cur_index = right_index;
			}
			else
			{
				m_data[cur_index] = m_data[left_index];
				cur_index = left_index;
			}
		}
		//有左无右
		else if (left_index <= m_size)
		{
			//只有左边的话一定是最后一个子节点放到头上面
			//就行再让下标数减少1位就好
			m_data[cur_index] = m_data[left_index];
			m_size -= 1;
			return true;
		}
		//无子节点
		else
		{
			//将当前最后一个节点补齐到当前位置
			m_data[cur_index] = m_data[m_size];
			m_size -= 1;

			//调整下标
			//得到子节点、父节点
			int child_index = cur_index;//子节点
			int parent_index = cur_index / 2;//父节点

			while (child_index > 1 &&
				m_data[parent_index] < m_data[child_index])
			{
				//数据交换
				T t = m_data[parent_index];
				m_data[parent_index] = m_data[child_index];
				m_data[child_index] = t;

				cur_index = child_index;
				parent_index = child_index / 2;
			}
			return true;
		}
	}
}


template <typename T>
void CMaxHeap<T>::Clear()
{
	m_size = 0;
}

template <typename T>
int CMaxHeap<T>::Size()
{
	return m_size;
}
 
 
HeapSort.cpp 
 
 

猜你喜欢

转载自blog.csdn.net/qq_18604483/article/details/78201601
今日推荐