算法导论第三版-第6章堆排序操作完整代码(建堆、插入、删除、排序等)

本文介绍了一个基于最大堆实现的堆排序算法,并详细展示了如何通过调整节点位置来维护堆的特性。此外,还提供了增加关键字、插入新元素、提取最大值及删除指定元素等操作的具体实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

程序如下:

// heap_sort.cpp : 定义控制台应用程序的入口点。
//
#include<iostream>
#include<algorithm>
using namespace std;

#define N 1000
#define PARENT(i) (i)>>1
#define LEFT(i) (i)<<1;
#define RIGHT(i) ((i)<<1)+1

class Heap
{
public:
	//成员变量
	int A[N + 1];
	int length;
	int heap_size;
	//构造与析构
	Heap() {}
	Heap(int size) :length(size), heap_size(size) {}
	~Heap() {}
	//功能函数
	void Max_Heapify(int i);
	void Build_Max_Heap();
	void HeapSort(int A[]);
	//优先队列函数
	void Heap_Increase_Key(int i,int key);
	void Max_Heap_Insert(int key);
	int Heap_Maximum();
	int Heap_Extract_Max();
	void Heap_Delete(int i);
	//辅助函数
	void Print();
	void Print1();

};
//使以i结点为根结点的子树成为堆,调用条件是确定i的左右子树已经是堆,时间是O(lgn)
//递归方法
void Heap::Max_Heapify(int i)
{
	int l = LEFT(i);
	int r = RIGHT(i);
	int largest;
	//选择i、i的左、i的右三个结点中值最大的结点
	if (l<heap_size&&A[l]>A[i])
		largest = l;
	else largest = i;
	if (r<heap_size&&A[r]>A[largest])
		largest = r;
	//如果根结点值最大,已经满足堆的条件,函数停止
	//否则
	if (largest != i)
	{
		//根结点与值最大的结点交换
		swap(A[i],A[largest]);
		//交换可能破坏子树的堆,重新调整子树
		Max_Heapify(largest);
	}

}

//建堆,时间复杂度O(nlgn)
void Heap::Build_Max_Heap()
{
	heap_size = length;
	//从中间开始依次向前调整每个结点,使得符合堆的性质
	for (int i = length / 2; i >= 0; i--)
		Max_Heapify(i);
}

//堆排序,时间复杂度O(nlgn)
void Heap::HeapSort(int A[])
{
	//建立一个最大堆
	Build_Max_Heap();
	//每次将前i个元素构成最大堆
	for (int i = length - 1; i >= 1; i--)
	{
		//将前i个元素中的最大值存入到A[i]中
		swap(A[0],A[i]);
		//堆的大小减一
		heap_size--;
		//只有堆顶的性质可能会被破坏
		Max_Heapify(0);
	
	}
}

//将元素i的关键字增加到key,要求key>=A[i]
void Heap::Heap_Increase_Key(int i, int key)
{
	if (key < A[i])
	{
		cout << "new key is smaller than current key" << endl;
		exit(0);
	}
	A[i] = key;
	//跟父结点比较,若A[PARENT(i)]<A[i],则交换
	//若运行到某个结点时A[PARENT(i)]>A[i],就跳出循环
	while (A[PARENT(i)]>0 && A[PARENT(i)] < A[i])
	{
		swap(A[PARENT(i)],A[i]);
		i = PARENT(i);
	}
}

//将key插入到集合A中
void Heap::Max_Heap_Insert(int key)
{
	if (heap_size == N)
	{
		cout << "heap is full" << endl;
		exit(0);
		
	}
	heap_size++; length++;
	A[heap_size - 1] = -0x7fffffff;
	Heap_Increase_Key(heap_size - 1, key);
}

//返回A中最大关键字,时间O(1)
int Heap::Heap_Maximum()
{
	return A[0];
}

//去掉并返回A中最大关键字,时间复杂度O(lgn)
int Heap::Heap_Extract_Max()
{
	if (heap_size < 0)
	{
		cout << "heap underflow" << endl;
		exit(0);
	}
	//取出最大值
	int max = A[0];
	//将最后一个元素补到最大值的位置
	A[0] = A[heap_size - 1];
	heap_size--;
	//重新调整根结点
	Max_Heapify(0);
	//返回最大值
	return max;
}

//删除堆中第i个元素
void Heap::Heap_Delete(int i)
{
	if (i > heap_size)
	{
		cout << "there is no node i" << endl;
		exit(0);
	}
	//把最后一个元素补到第i个元素的位置
	int key = A[heap_size - 1];
	heap_size--;
	//如果新值比原来A[i]大,则向上调整
	if (key > A[i])
		Heap_Increase_Key(i,key);
	else//否则,向下调整
	{
		A[i] = key;
		Max_Heapify(i);
		A[heap_size] = 0;
	}
}
void Heap::Print()
{
	int i;
	for (i = 0; i < heap_size; i++)
	{
		if (i > 0)cout << ',';
		else cout << "==>A={";
		cout << A[i];
	}
	cout << '}' << endl;
}

void Heap::Print1()
{
	int i;
	cout << "==>A={";
	for (i = 0; i < length; i++)
	{
		if (A[i] > 0)
		{
			cout << A[i] << " ";
		}
	}
	cout << '}' << endl;
}
void main()
{
	Heap a(13);
	a.A[0] = 1; a.A[1] = 9; a.A[2] = 10; a.A[3] = 2; a.A[4] = 7;
	a.A[5] = 5; a.A[6] = 6; a.A[7] = 4; a.A[8] = 13; a.A[9] = 3;
	a.A[10] = 18; a.A[11] = 11; a.A[12] = 100;
	a.Build_Max_Heap();
	cout << "建立最大堆结果:" << endl;
	a.Print();
	a.Heap_Delete(2);
	cout << "删除堆中A[2]结果:" << endl;
	a.Print();
	a.Heap_Extract_Max();
	cout << "取出堆中最大值后结果:" << endl;
	a.Print();
	a.Heap_Increase_Key(8, 15);
	cout << "将A[8]值增加到15后结果:" << endl;
	a.Print();
	a.Max_Heap_Insert(56);
	cout << "将值56插入最大堆后的结果:" << endl;
	a.Print();
	a.HeapSort(a.A);
	cout << "堆排序结果:" << endl;
	a.Print1();
	system("pause");
}
执行结果:






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值