/*
* 维护堆的性质
* @param arr 数组
* @param n 数组长度
* @param i 待维护节点下标
*/voidheapify(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. 删除堆顶元素
//删除堆顶元素intheap_delet_max(int* arr,int&n){int val = arr[0];//堆顶元素swap(arr[0],arr[n-1]);//交换堆顶元素和最后一个元素值--n;//数组大小-1for(int i = n /2-1; i >=0;--i)heapify(arr, n, i);//重新建堆return val;//返回堆顶元素值}
4. 删除任意元素(假设元素各不相同)
//删除任意元素 默认堆内各个元素不相同intheap_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<<"输入数据值不存在!";return1;}for(;i<n;++i)//每次进行交换,将数据前移swap(arr[i],arr[i+1]);--n;//数据大小-1//重新建堆for(i = n /2-1; i >=0;--i)heapify(arr, n, i);return0;}
5. 堆内插入元素
//堆中插元素入voidheap_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. 堆排序
voidheapsort(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>usingnamespace std;#include"heapsort02.h"#defineMAX9999intmain(){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");return0;}
8. 输出结果
输入数据个数:6
输入正整数:
2418471210
打印原数据:24 18471210
打印建堆后的数据:24 18107124
删除堆顶元素后且重新建堆后的数据:18 121074
输入要删除的元素值:10
删除元素且重新建堆后的数据:18 1274
输入需要插入的元素值:5
插入元素且重新建堆后的数据:18 12745
打印堆排序后的数据:4 571218
请按任意键继续. ..
Process returned 0(0x0) execution time:24.376 s
Press any key to continue.