二叉堆的建立插入删除 堆排序(大顶堆) [C语言数组实现大]代码

本文详细介绍了二叉堆的性质维护、建堆、删除堆顶元素、删除任意元素、插入元素以及堆排序的过程。通过代码示例展示了如何在C++中实现这些操作,并给出了具体的操作结果,包括建堆后的数据、删除元素后的数据、插入元素后的数据以及堆排序后的数据。此外,还提供了完整的代码实现,便于读者理解和学习。

1. 堆性质维护

/*
* 维护堆的性质
* @param arr 数组
* @param n 数组长度
* @param i 待维护节点下标
*/

void heapify(int* arr, int n, int i) {
	int largest = i;
	int lson = i * 2 + 1;//左孩子结点下标
	int rson = i * 2 + 2;//右孩子结点下标
	if (lson < n && arr[largest] < arr[lson])
		largest = lson;
	if (rson < n && arr[largest] < arr[rson])
		largest = rson;
	if (largest != i) {
		swap(arr[largest], arr[i]);//交换父结点和子节点的最大元素
		heapify(arr, n, largest);//递归直到叶子结点
	}
}

2. 建堆

	//n为数组元素个数 这里i为第一个有叶子结点的结点下标
    for (int i = n / 2 - 1; i >= 0; --i)
		heapify(arr, n, i);//每次进行堆维护

3. 删除堆顶元素

//删除堆顶元素
int heap_delet_max(int* arr,int &n){
	int val = arr[0];//堆顶元素
	swap(arr[0],arr[n-1]);//交换堆顶元素和最后一个元素值
	--n;//数组大小-1
    for (int i = n / 2 - 1; i >= 0; --i)
		heapify(arr, n, i);//重新建堆
	return val;//返回堆顶元素值
}

4. 删除任意元素(假设元素各不相同)

//删除任意元素 默认堆内各个元素不相同
int heap_delet_val(int* arr, int val,int &n){
	int i;
	for(i = 0; i < n; ++i){
		if(arr[i] == val)//找到了第一个删除元素的值
			break;
	}
	if(i==n-1&&arr[i]!=val){//没有找到删除元素值
        cout<<"输入数据值不存在!";
        return 1;
    }
	for(;i<n;++i)//每次进行交换,将数据前移
        swap(arr[i],arr[i+1]);
    --n;//数据大小-1
	//重新建堆
    for (i = n / 2 - 1; i >= 0; --i)
		heapify(arr, n, i);
    return 0;
}

5. 堆内插入元素

//堆中插元素入
void heap_insert_val(int* arr,int val,int &n){
	++n;//数组大小+1
	arr[n-1] = val;//将插入值放到最后一元素位置
	//重新建堆
	int i;
    for (i = n / 2 - 1; i >= 0; --i)
		heapify(arr, n, i);//重新建堆
}

6. 堆排序

void heapsort(int* arr, int n) {
	int i;
	// 建堆
	for (i = n / 2 - 1; i >= 0; --i)
		heapify(arr, n, i);
	// 排序
	for (i = n - 1; i > 0; --i) {
		swap(arr[i], arr[0]);//每次将堆顶元素(最大值)和数组末位元素交换
		heapify(arr, i, 0);//对除去数组最后一个元素的新堆进行重建
	}
}

7. 代码示例

#include <iostream>
using namespace std;
#include "heapsort02.h"
#define MAX 9999

int main(){
    int arr[MAX];
    int n;
    cout<<"输入数据个数:";
    cin>>n;
    if(n>MAX){
        cout<<"输入数据过大!"<<endl;
        system("pause");
        exit(1);
    }
    cout<<"输入正整数:"<<endl;
    for(int i = 0;i<n;++i)
        cin>>arr[i];

    cout<<"打印原数据:";
    for(int i = 0;i<n;++i)
        cout<<arr[i]<<"  ";
    cout<<endl;

    cout<<"打印建堆后的数据:";
    for (int i = n / 2 - 1; i >= 0; --i)
		heapify(arr, n, i);
    for(int i = 0;i<n;++i)
        cout<<arr[i]<<"  ";
    cout<<endl;

    cout<<"删除堆顶元素后且重新建堆后的数据:";
    heap_delet_max(arr,n);//返回堆顶元素
    for(int i = 0;i<n;++i)
        cout<<arr[i]<<"  ";
    cout<<endl;

    //堆删除任意元素:
    int del_val;
    cout<<"输入要删除的元素值:";
    cin>>del_val;
    if(heap_delet_val(arr,del_val,n)==0){
        cout<<"删除元素且重新建堆后的数据:";
        for(int i = 0;i<n;++i)
            cout<<arr[i]<<"  ";
        cout<<endl;
    }
    else
        cout<<endl;;


    //堆中插入元素:
    int add_val;
    cout<<"输入需要插入的元素值:";
    cin>>add_val;
    heap_insert_val(arr,add_val,n);
    cout<<"插入元素且重新建堆后的数据:";
    for(int i = 0;i<n;++i)
        cout<<arr[i]<<"  ";
    cout<<endl;

    //最后进行堆排序
    cout<<"打印堆排序后的数据:";
    heapsort(arr,n);
    for(int i = 0;i<n;++i)
        cout<<arr[i]<<"  ";
    cout<<endl;

    system("pause");
    return 0;
}

8. 输出结果

输入数据个数:6
输入正整数:
24
18
4
7
12
10
打印原数据:24  18  4  7  12  10
打印建堆后的数据:24  18  10  7  12  4
删除堆顶元素后且重新建堆后的数据:18  12  10  7  4
输入要删除的元素值:10
删除元素且重新建堆后的数据:18  12  7  4
输入需要插入的元素值:5
插入元素且重新建堆后的数据:18  12  7  4  5
打印堆排序后的数据:4  5  7  12  18
请按任意键继续. . .

Process returned 0 (0x0)   execution time : 24.376 s
Press any key to continue.
  • ——————END-2022-03-23——————
  • 个人学习笔记,如有纰漏,敬请指正。
  • 感谢您的阅读。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

苡荏

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

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

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

打赏作者

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

抵扣说明:

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

余额充值