C++堆排序---创建最大堆类实现堆排序

创建最大堆类

class Maxheap
{
    
    
private:
	//存放元素的堆数组
	int* heap;
	//数组的空间长度
	int arrayLength;
	//数组中元素的个数
	int heapSize;
	//扩容数组的函数
	void changeLength(int*& old, int oldLength, int newLength)
	{
    
    
		if (oldLength <= newLength)
		{
    
    
			cout << "newlength should > oldlength" << endl;
			return;
		}
		//创建新数组
		int* temp = new int[newLength];
		//复制
		for (int index = 1; index < oldLength; index++)
		{
    
    
			temp[index] = old[index];
		}
		delete[] old;
		old = temp;
	}
public:
	Maxheap(int capacity = 10)
	{
    
    
		//数组从1开始
		heap = new int[capacity + 1];
		arrayLength = capacity + 1;
		heapSize = 0;
	}
	//插入元素
	void push(int element)
	{
    
    
		if (heapSize == arrayLength - 1)
		{
    
    
			int newLength = arrayLength * 2;
			changeLength(heap, arrayLength, newLength);
		}
		//获取要添加的节点位置的索引
		//并将元素个数+1
		int currentNode = ++heapSize;
		//当不是根节点且根节点元素小于插入的元素
		while (currentNode != 1 && element > heap[currentNode / 2])
		{
    
    
			//将根节点元素下移
			heap[currentNode] = heap[currentNode / 2];
			//将元素索引上移
			currentNode = currentNode / 2;
		}
		heap[currentNode] = element;
	}
	//返回优先级最高的元素
	int top()
	{
    
    
		if (heapSize == 0)
		{
    
    
			cout << "the heap is empty" << endl;
			//这里正常应该是抛出异常,这里省略了
			return -111111111;
		}
		return heap[1];
	}
	//删除最大的元素
	void pop()
	{
    
    
		if (heapSize == 0)
		{
    
    
			cout << "the heap is empty" << endl;
			return;
		}
		int lastElement = heap[heapSize--];
		int currentNode = 1;
		int child = 2;
		while (child <= heapSize)
		{
    
    
			//找heap[currentNode]的更大的孩子
			if (child < heapSize && heap[child] < heap[child + 1])
			{
    
    
				child++;
			}
			if (lastElement > heap[child])
			{
    
    
				break;
			}
			heap[currentNode] = heap[child];
			currentNode = child;
			child *= 2;
		}
		heap[currentNode] = lastElement;
	}
	//将一个数组初始化为最大堆
	void initialize(int* array, int size)
	{
    
    
		delete[] heap;
		//先生成完全二叉树
		heap = array;
		heapSize = size;
		//找到最后一个具有孩子的节点
		for (int root = heapSize / 2; root >= 1; root--)
		{
    
    
			int rootEle = heap[root];
			int child = root * 2;
			while (child <= heapSize)
			{
    
    
				//找孩子中较大的那一个
				if (child < heapSize && heap[child] < heap[child + 1])
				{
    
    
					child++;
				}
				//如果根元素大于最大的孩子,就直接结束循环
				if (rootEle >= heap[child])
				{
    
    
					break;
				}
				//如果根元素比最大的孩子小,就将孩子上移
				heap[child / 2] = heap[child];
				//移到下一层,直到为根元素找到合适的位置
				child *= 2;
			}
			//将原本的根元素放到合适的位置上去
			heap[child / 2] = rootEle;
		}
	}
	friend ostream& operator<<(ostream& cout, Maxheap& m);
};
ostream& operator<<(ostream& cout, Maxheap& m)
{
    
    
	for (int index = 1; index <= m.heapSize; index++)
	{
    
    
		cout << m.heap[index] << " ";
	}
	return cout;
}

堆排序方法

void heapSort(int a[], int size)
{
    
    
	Maxheap m;
	m.initialize(a, size);
	for (int i = size - 1; i >= 1; i--)
	{
    
    
		int x = m.top();
		m.pop();
		//讲弹出的元素放在数组的最后面,不再新开辟数组
		a[i + 1] = x;
	}
}

完整代码,使用随机数生成要排序的数

随机数范围为0-max(用户手动输入)

#include<iostream>
#include<ctime>
using namespace std;
//最大堆类
class Maxheap
{
    
    
private:
	//存放元素的堆数组
	int* heap;
	//数组的空间长度
	int arrayLength;
	//数组中元素的个数
	int heapSize;
	void changeLength(int*& old, int oldLength, int newLength)
	{
    
    
		if (oldLength <= newLength)
		{
    
    
			cout << "newlength should > oldlength" << endl;
			return;
		}
		//创建新数组
		int* temp = new int[newLength];
		//复制
		for (int index = 1; index < oldLength; index++)
		{
    
    
			temp[index] = old[index];
		}
		delete[] old;
		old = temp;
	}
public:
	Maxheap(int capacity = 10)
	{
    
    
		//数组从1开始
		heap = new int[capacity + 1];
		arrayLength = capacity + 1;
		heapSize = 0;
	}
	//插入元素
	void push(int element)
	{
    
    
		if (heapSize == arrayLength - 1)
		{
    
    
			int newLength = arrayLength * 2;
			changeLength(heap, arrayLength, newLength);
		}
		//获取要添加的节点位置的索引
		//并将元素个数+1
		int currentNode = ++heapSize;
		//当不是根节点且根节点元素小于插入的元素
		while (currentNode != 1 && element > heap[currentNode / 2])
		{
    
    
			//将根节点元素下移
			heap[currentNode] = heap[currentNode / 2];
			//将元素索引上移
			currentNode = currentNode / 2;
		}
		heap[currentNode] = element;
	}
	//返回优先级最高的元素
	int top()
	{
    
    
		if (heapSize == 0)
		{
    
    
			cout << "the heap is empty" << endl;
			return -111111111;
		}
		return heap[1];
	}
	//删除最大的元素
	void pop()
	{
    
    
		if (heapSize == 0)
		{
    
    
			cout << "the heap is empty" << endl;
			return;
		}
		int lastElement = heap[heapSize--];
		int currentNode = 1;
		int child = 2;
		while (child <= heapSize)
		{
    
    
			//找heap[currentNode]的更大的孩子
			if (child < heapSize && heap[child] < heap[child + 1])
			{
    
    
				child++;
			}
			if (lastElement > heap[child])
			{
    
    
				break;
			}
			heap[currentNode] = heap[child];
			currentNode = child;
			child *= 2;
		}
		heap[currentNode] = lastElement;
	}
	//将一个数组初始化为最大堆
	void initialize(int* array, int size)
	{
    
    
		delete[] heap;
		//先生成完全二叉树
		heap = array;
		heapSize = size;
		//找到最后一个具有孩子的节点
		for (int root = heapSize / 2; root >= 1; root--)
		{
    
    
			int rootEle = heap[root];
			int child = root * 2;
			while (child <= heapSize)
			{
    
    
				//找孩子中较大的那一个
				if (child < heapSize && heap[child] < heap[child + 1])
				{
    
    
					child++;
				}
				//如果根元素大于最大的孩子,就直接结束循环
				if (rootEle >= heap[child])
				{
    
    
					break;
				}
				//如果根元素比最大的孩子小,就将孩子上移
				heap[child / 2] = heap[child];
				//移到下一层,直到为根元素找到合适的位置
				child *= 2;
			}
			//将原本的根元素放到合适的位置上去
			heap[child / 2] = rootEle;
		}
	}
	friend ostream& operator<<(ostream& cout, Maxheap& m);
};
ostream& operator<<(ostream& cout, Maxheap& m)
{
    
    
	for (int index = 1; index <= m.heapSize; index++)
	{
    
    
		cout << m.heap[index] << " ";
	}
	return cout;
}
//对数组a进行堆排序
void heapSort(int a[], int size)
{
    
    
	Maxheap m;
	m.initialize(a, size);
	for (int i = size - 1; i >= 1; i--)
	{
    
    
		int x = m.top();
		m.pop();
		a[i + 1] = x;
	}
}
int main()
{
    
    
	//用户手动输入要排序数据的总数
	int n = 0;
	cout << "请输入要排序的数的个数" << endl;
	cin >> n;
	//用户输入数的范围
	cout << "请输入参与排序的数的最大值" << endl;
	int max = 0;
	cin >> max;
	//随机数种子
	srand((unsigned)time(NULL));
	int* a = new int[n + 1];
	//指定a[0]的值为0,从索引1-n排序
	a[0] = 0;
	//使用随机数初始化要进行排序的数组
	for (int index = 1; index <= n; index++)
	{
    
    
		a[index] = rand() % (max + 1);
	}
	//进行堆排序
	heapSort(a, n);
	//输出结果
	for (int index = 1; index <= n; index++) 
	{
    
    
		cout << a[index] << " ";
	}
}

猜你喜欢

转载自blog.csdn.net/weixin_46841376/article/details/113776949